Skip to content

Instantly share code, notes, and snippets.

@aead
Created March 13, 2020 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aead/6dd689e40b14ea45c7386f199e5a2105 to your computer and use it in GitHub Desktop.
Save aead/6dd689e40b14ea45c7386f199e5a2105 to your computer and use it in GitHub Desktop.
Argon2 closure API
diff --git a/argon2/argon2.go b/argon2/argon2.go
index b423fea..9535653 100644
--- a/argon2/argon2.go
+++ b/argon2/argon2.go
@@ -99,6 +99,37 @@ func IDKey(password, salt []byte, time, memory uint32, threads uint8, keyLen uin
return deriveKey(argon2id, password, salt, nil, nil, time, memory, threads, keyLen)
}
+func New(time, memory uint32, threads uint8) func([]byte, []byte, uint32) []byte {
+ if time < 1 {
+ panic("argon2: number of rounds too small")
+ }
+ if threads < 1 {
+ panic("argon2: parallelism degree too low")
+ }
+
+ mem := memory / (syncPoints * uint32(threads)) * (syncPoints * uint32(threads))
+ if mem < 2*syncPoints*uint32(threads) {
+ mem = 2 * syncPoints * uint32(threads)
+ }
+ pool := sync.Pool{
+ New: func() interface{} {
+ b := make([]block, mem)
+ return &b
+ },
+ }
+
+ return func(password, salt []byte, keyLen uint32) []byte {
+ blocks := pool.Get().(*[]block)
+ defer pool.Put(blocks)
+
+ h0 := initHash(password, salt, nil, nil, time, memory, uint32(threads), keyLen, argon2id)
+ B := initBlocks(&h0, *blocks, uint32(threads))
+ processBlocks(B, time, mem, uint32(threads), argon2id)
+ key := extractKey(B, mem, uint32(threads), keyLen)
+ return key
+ }
+}
+
func deriveKey(mode int, password, salt, secret, data []byte, time, memory uint32, threads uint8, keyLen uint32) []byte {
if time < 1 {
panic("argon2: number of rounds too small")
@@ -112,7 +143,8 @@ func deriveKey(mode int, password, salt, secret, data []byte, time, memory uint3
if memory < 2*syncPoints*uint32(threads) {
memory = 2 * syncPoints * uint32(threads)
}
- B := initBlocks(&h0, memory, uint32(threads))
+ B := make([]block, memory)
+ B = initBlocks(&h0, B, uint32(threads))
processBlocks(B, time, memory, uint32(threads), mode)
return extractKey(B, memory, uint32(threads), keyLen)
}
@@ -155,11 +187,11 @@ func initHash(password, salt, key, data []byte, time, memory, threads, keyLen ui
return h0
}
-func initBlocks(h0 *[blake2b.Size + 8]byte, memory, threads uint32) []block {
+func initBlocks(h0 *[blake2b.Size + 8]byte, blocks []block, threads uint32) []block {
var block0 [1024]byte
- B := make([]block, memory)
+ B := blocks
for lane := uint32(0); lane < threads; lane++ {
- j := lane * (memory / threads)
+ j := lane * (uint32(len(B)) / threads)
binary.LittleEndian.PutUint32(h0[blake2b.Size+4:], lane)
binary.LittleEndian.PutUint32(h0[blake2b.Size:], 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment