Created
March 13, 2020 18:11
-
-
Save aead/6dd689e40b14ea45c7386f199e5a2105 to your computer and use it in GitHub Desktop.
Argon2 closure API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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