Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[Ready] Implement Keystore primitives EIP-2333 #60

Merged
merged 3 commits into from
Jun 2, 2020
Merged

Conversation

mratsim
Copy link
Contributor

@mratsim mratsim commented Jun 2, 2020

This implements keystore primitives for EIP-2333 (draft)
ethereum/EIPs#2333

This will unblock status-im/nimbus-eth2#1093

cc @zah

Ready:

Note that the spec requires over 16KB of stack for parent_SK_to_Lamport_PK
image

the lamport_0 and lamport_1 are of size 255 * 32 bytes, in the code we reorder the spec and reuse the same lamport buffer.

# 2. lamport_0 = IKM_to_lamport_SK(IKM, salt)
# TODO: this uses 8KB and has a high stack-overflow potential
var lamport {.noInit.}: array[255, array[32, byte]]
ikm.ikm_to_lamport_SK(salt, lamport)
# TODO: unclear inclusive/exclusive ranges in spec
# assuming exclusive:
# https://github.com/ethereum/EIPs/issues/2337#issuecomment-637521421
# 6. for i = 0 to 255
# lamport_PK = lamport_PK | SHA256(lamport_0[i])
for i in 0 ..< 255:
ctx.update(sha256.digest(lamport[i]).data)
# 3. not_IKM = flip_bits(parent_SK)
# We can flip the bit of the IKM instead
# as flipping bits of milagro representation (Montgomery)
# doesn't make sense
var not_ikm {.noInit.}: array[32, byte]
for i in 0 ..< 32:
not_ikm[i] = not ikm[i]
# 4. lamport_1 = IKM_to_lamport_SK(not_IKM, salt)
# We reuse the previous buffer to limit stack usage
not_ikm.ikm_to_lamport_SK(salt, lamport)
# TODO: inclusive/exclusive range?
# 7. for i = 0 to 255
# lamport_PK = lamport_PK | SHA256(lamport_1[i])
for i in 0 ..< 255:
ctx.update(sha256.digest(lamport[i]).data)

We could further divide stack usage by 255 (!) if we have an alternative HKDF Expand iterator:

let oArray = cast[ptr UncheckedArray[byte]](output)
for i in 0 .. N:
ctx.init(prk.data)
# T(0) = empty string
if i != 0:
ctx.update(t.data)
ctx.update(info)
ctx.update([uint8(i+1)])
discard ctx.finish(t.data)
let iStart = i * HashLen
let size = min(HashLen, output.len - iStart)
copyMem(oArray[iStart].addr, t.data.addr, size)

@mratsim mratsim force-pushed the keystore-eip2333 branch from ba7a2fb to 96f2033 Compare June 2, 2020 14:49
@mratsim mratsim changed the title [WIP] Implement Keystore primitives EIP-2333 [Ready] Implement Keystore primitives EIP-2333 Jun 2, 2020
@mratsim mratsim requested a review from zah June 2, 2020 14:50
@zah zah merged commit 1a18d0d into master Jun 2, 2020
@mratsim mratsim deleted the keystore-eip2333 branch July 22, 2020 08:29
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants