mirror of
https://github.com/waku-org/nwaku.git
synced 2025-01-28 15:46:33 +00:00
863 lines
26 KiB
Nim
863 lines
26 KiB
Nim
#
|
|
#
|
|
# NimCrypto
|
|
# (c) Copyright 2016-2018 Eugene Kabanov
|
|
#
|
|
# See the file "LICENSE", included in this
|
|
# distribution, for details about the copyright.
|
|
#
|
|
|
|
## This module implements RIPEMD set of cryptographic hash functions,
|
|
## designed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
|
|
## [http://www.esat.kuleuven.be/~bosselae/ripemd160/pdf/AB-9601/AB-9601.pdf]
|
|
##
|
|
## This module is Nim adoptation of original C source code by
|
|
## Antoon Bosselaers.
|
|
## [https://homes.esat.kuleuven.be/~bosselae/ripemd160/ps/AB-9601/rmd160.c]
|
|
##
|
|
## This module includes support of RIPEMD-128/160/256/320.
|
|
##
|
|
## Tests made according to official test vectors
|
|
## [https://homes.esat.kuleuven.be/~bosselae/ripemd160.html].
|
|
import hash, utils
|
|
export hash
|
|
|
|
{.deadCodeElim: on.}
|
|
|
|
type
|
|
RipemdContext*[bits: static[int]] = object
|
|
count: array[2, uint32]
|
|
state: array[bits div 32, uint32]
|
|
buffer: array[64, byte]
|
|
|
|
ripemd128* = RipemdContext[128]
|
|
ripemd160* = RipemdContext[160]
|
|
ripemd256* = RipemdContext[256]
|
|
ripemd320* = RipemdContext[320]
|
|
ripemd* = ripemd128 | ripemd160 | ripemd256 | ripemd320
|
|
|
|
# Five basic functions F(), G() and H()
|
|
template F(x, y, z: untyped): untyped =
|
|
# x^y^z
|
|
((x) xor (y) xor (z))
|
|
|
|
template G(x, y, z: untyped): untyped =
|
|
# (x&y)|(~x&z)
|
|
(((x) and (y)) or (not (x) and (z)))
|
|
|
|
template H(x, y, z: untyped): untyped =
|
|
# (x|~y)^z
|
|
(((x) or not (y)) xor (z))
|
|
|
|
template I(x, y, z: untyped): untyped =
|
|
# (x&z)|(y&~z)
|
|
(((x) and (z)) or ((y) and not (z)))
|
|
|
|
template J(x, y, z: untyped): untyped =
|
|
# x^(y|~z)
|
|
((x) xor ((y) or not (z)))
|
|
|
|
# Eight basic operations FF() through III() for 128 and 256 bits
|
|
template FF128(a, b, c, d, x, s: untyped): void =
|
|
(a) = (a) + F((b), (c), (d)) + (x)
|
|
(a) = ROL(cast[uint32](a), (s))
|
|
|
|
template GG128(a, b, c, d, x, s: untyped): void =
|
|
(a) = (a) + G((b), (c), (d)) + (x) + 0x5A827999'u32
|
|
(a) = ROL(cast[uint32](a), (s))
|
|
|
|
template HH128(a, b, c, d, x, s: untyped): void =
|
|
(a) = (a) + H((b), (c), (d)) + (x) + 0x6ED9EBA1'u32
|
|
(a) = ROL(cast[uint32](a), (s))
|
|
|
|
template II128(a, b, c, d, x, s: untyped): void =
|
|
(a) = (a) + I((b), (c), (d)) + (x) + 0x8F1BBCDC'u32
|
|
(a) = ROL(cast[uint32](a), (s))
|
|
|
|
template FFF128(a, b, c, d, x, s: untyped): void =
|
|
(a) = (a) + F((b), (c), (d)) + (x)
|
|
(a) = ROL(cast[uint32](a), (s))
|
|
|
|
template GGG128(a, b, c, d, x, s: untyped): void =
|
|
(a) = (a) + G((b), (c), (d)) + (x) + 0x6D703EF3'u32
|
|
(a) = ROL(cast[uint32](a), (s))
|
|
|
|
template HHH128(a, b, c, d, x, s: untyped): void =
|
|
(a) = (a) + H((b), (c), (d)) + (x) + 0x5C4DD124'u32
|
|
(a) = ROL(cast[uint32](a), (s))
|
|
|
|
template III128(a, b, c, d, x, s: untyped): void =
|
|
(a) = (a) + I((b), (c), (d)) + (x) + 0x50A28BE6'u32
|
|
(a) = ROL((a), (s))
|
|
|
|
# Ten basic operations FF() through III() for 160 and 320 bits
|
|
template FF160(a, b, c, d, e, x, s: untyped): void =
|
|
(a) = (a) + F((b), (c), (d)) + (x)
|
|
(a) = ROL(cast[uint32](a), (s)) + (e)
|
|
(c) = ROL(cast[uint32](c), 10)
|
|
|
|
template GG160(a, b, c, d, e, x, s: untyped): void =
|
|
(a) = (a) + G((b), (c), (d)) + (x) + 0x5A827999'u32
|
|
(a) = ROL(cast[uint32](a), (s)) + (e)
|
|
(c) = ROL(cast[uint32](c), 10)
|
|
|
|
template HH160(a, b, c, d, e, x, s: untyped): void =
|
|
(a) = (a) + H((b), (c), (d)) + (x) + 0x6ED9EBA1'u32
|
|
(a) = ROL(cast[uint32](a), (s)) + (e)
|
|
(c) = ROL(cast[uint32](c), 10)
|
|
|
|
template II160(a, b, c, d, e, x, s: untyped): void =
|
|
(a) = (a) + I((b), (c), (d)) + (x) + 0x8F1BBCDC'u32
|
|
(a) = ROL(cast[uint32](a), (s)) + (e)
|
|
(c) = ROL(cast[uint32](c), 10)
|
|
|
|
template JJ160(a, b, c, d, e, x, s: untyped): void =
|
|
(a) = (a) + J((b), (c), (d)) + (x) + 0xA953FD4E'u32
|
|
(a) = ROL(cast[uint32](a), (s)) + (e)
|
|
(c) = ROL(cast[uint32](c), 10)
|
|
|
|
template FFF160(a, b, c, d, e, x, s: untyped): void =
|
|
(a) = (a) + F((b), (c), (d)) + (x)
|
|
(a) = ROL(cast[uint32](a), (s)) + (e)
|
|
(c) = ROL(cast[uint32](c), 10)
|
|
|
|
template GGG160(a, b, c, d, e, x, s: untyped): void =
|
|
(a) = (a) + G((b), (c), (d)) + (x) + 0x7A6D76E9'u32
|
|
(a) = ROL(cast[uint32](a), (s)) + (e)
|
|
(c) = ROL(cast[uint32](c), 10)
|
|
|
|
template HHH160(a, b, c, d, e, x, s: untyped): void =
|
|
(a) = (a) + H((b), (c), (d)) + (x) + 0x6D703EF3'u32
|
|
(a) = ROL(cast[uint32](a), (s)) + (e)
|
|
(c) = ROL(cast[uint32](c), 10)
|
|
|
|
template III160(a, b, c, d, e, x, s: untyped): void =
|
|
(a) = (a) + I((b), (c), (d)) + (x) + 0x5C4DD124'u32
|
|
(a) = ROL(cast[uint32](a), (s)) + (e)
|
|
(c) = ROL(cast[uint32](c), 10)
|
|
|
|
template JJJ160(a, b, c, d, e, x, s: untyped): void =
|
|
(a) = (a) + J((b), (c), (d)) + (x) + 0x50A28BE6'u32
|
|
(a) = ROL(cast[uint32](a), (s)) + (e)
|
|
(c) = ROL(cast[uint32](c), 10)
|
|
|
|
template LROUND128N1(a, b, c, d, x): void =
|
|
FF128(a, b, c, d, x[ 0], 11)
|
|
FF128(d, a, b, c, x[ 1], 14)
|
|
FF128(c, d, a, b, x[ 2], 15)
|
|
FF128(b, c, d, a, x[ 3], 12)
|
|
FF128(a, b, c, d, x[ 4], 5)
|
|
FF128(d, a, b, c, x[ 5], 8)
|
|
FF128(c, d, a, b, x[ 6], 7)
|
|
FF128(b, c, d, a, x[ 7], 9)
|
|
FF128(a, b, c, d, x[ 8], 11)
|
|
FF128(d, a, b, c, x[ 9], 13)
|
|
FF128(c, d, a, b, x[10], 14)
|
|
FF128(b, c, d, a, x[11], 15)
|
|
FF128(a, b, c, d, x[12], 6)
|
|
FF128(d, a, b, c, x[13], 7)
|
|
FF128(c, d, a, b, x[14], 9)
|
|
FF128(b, c, d, a, x[15], 8)
|
|
|
|
template LROUND128N2(a, b, c, d, x): void =
|
|
GG128(a, b, c, d, x[ 7], 7)
|
|
GG128(d, a, b, c, x[ 4], 6)
|
|
GG128(c, d, a, b, x[13], 8)
|
|
GG128(b, c, d, a, x[ 1], 13)
|
|
GG128(a, b, c, d, x[10], 11)
|
|
GG128(d, a, b, c, x[ 6], 9)
|
|
GG128(c, d, a, b, x[15], 7)
|
|
GG128(b, c, d, a, x[ 3], 15)
|
|
GG128(a, b, c, d, x[12], 7)
|
|
GG128(d, a, b, c, x[ 0], 12)
|
|
GG128(c, d, a, b, x[ 9], 15)
|
|
GG128(b, c, d, a, x[ 5], 9)
|
|
GG128(a, b, c, d, x[ 2], 11)
|
|
GG128(d, a, b, c, x[14], 7)
|
|
GG128(c, d, a, b, x[11], 13)
|
|
GG128(b, c, d, a, x[ 8], 12)
|
|
|
|
template LROUND128N3(a, b, c, d, x): void =
|
|
HH128(a, b, c, d, x[ 3], 11)
|
|
HH128(d, a, b, c, x[10], 13)
|
|
HH128(c, d, a, b, x[14], 6)
|
|
HH128(b, c, d, a, x[ 4], 7)
|
|
HH128(a, b, c, d, x[ 9], 14)
|
|
HH128(d, a, b, c, x[15], 9)
|
|
HH128(c, d, a, b, x[ 8], 13)
|
|
HH128(b, c, d, a, x[ 1], 15)
|
|
HH128(a, b, c, d, x[ 2], 14)
|
|
HH128(d, a, b, c, x[ 7], 8)
|
|
HH128(c, d, a, b, x[ 0], 13)
|
|
HH128(b, c, d, a, x[ 6], 6)
|
|
HH128(a, b, c, d, x[13], 5)
|
|
HH128(d, a, b, c, x[11], 12)
|
|
HH128(c, d, a, b, x[ 5], 7)
|
|
HH128(b, c, d, a, x[12], 5)
|
|
|
|
template LROUND128N4(a, b, c, d, x): void =
|
|
II128(a, b, c, d, x[ 1], 11)
|
|
II128(d, a, b, c, x[ 9], 12)
|
|
II128(c, d, a, b, x[11], 14)
|
|
II128(b, c, d, a, x[10], 15)
|
|
II128(a, b, c, d, x[ 0], 14)
|
|
II128(d, a, b, c, x[ 8], 15)
|
|
II128(c, d, a, b, x[12], 9)
|
|
II128(b, c, d, a, x[ 4], 8)
|
|
II128(a, b, c, d, x[13], 9)
|
|
II128(d, a, b, c, x[ 3], 14)
|
|
II128(c, d, a, b, x[ 7], 5)
|
|
II128(b, c, d, a, x[15], 6)
|
|
II128(a, b, c, d, x[14], 8)
|
|
II128(d, a, b, c, x[ 5], 6)
|
|
II128(c, d, a, b, x[ 6], 5)
|
|
II128(b, c, d, a, x[ 2], 12)
|
|
|
|
template RROUND128N1(a, b, c, d, x): void =
|
|
III128(a, b, c, d, x[ 5], 8)
|
|
III128(d, a, b, c, x[14], 9)
|
|
III128(c, d, a, b, x[ 7], 9)
|
|
III128(b, c, d, a, x[ 0], 11)
|
|
III128(a, b, c, d, x[ 9], 13)
|
|
III128(d, a, b, c, x[ 2], 15)
|
|
III128(c, d, a, b, x[11], 15)
|
|
III128(b, c, d, a, x[ 4], 5)
|
|
III128(a, b, c, d, x[13], 7)
|
|
III128(d, a, b, c, x[ 6], 7)
|
|
III128(c, d, a, b, x[15], 8)
|
|
III128(b, c, d, a, x[ 8], 11)
|
|
III128(a, b, c, d, x[ 1], 14)
|
|
III128(d, a, b, c, x[10], 14)
|
|
III128(c, d, a, b, x[ 3], 12)
|
|
III128(b, c, d, a, x[12], 6)
|
|
|
|
template RROUND128N2(a, b, c, d, x): void =
|
|
HHH128(a, b, c, d, x[ 6], 9)
|
|
HHH128(d, a, b, c, x[11], 13)
|
|
HHH128(c, d, a, b, x[ 3], 15)
|
|
HHH128(b, c, d, a, x[ 7], 7)
|
|
HHH128(a, b, c, d, x[ 0], 12)
|
|
HHH128(d, a, b, c, x[13], 8)
|
|
HHH128(c, d, a, b, x[ 5], 9)
|
|
HHH128(b, c, d, a, x[10], 11)
|
|
HHH128(a, b, c, d, x[14], 7)
|
|
HHH128(d, a, b, c, x[15], 7)
|
|
HHH128(c, d, a, b, x[ 8], 12)
|
|
HHH128(b, c, d, a, x[12], 7)
|
|
HHH128(a, b, c, d, x[ 4], 6)
|
|
HHH128(d, a, b, c, x[ 9], 15)
|
|
HHH128(c, d, a, b, x[ 1], 13)
|
|
HHH128(b, c, d, a, x[ 2], 11)
|
|
|
|
template RROUND128N3(a, b, c, d, x): void =
|
|
GGG128(a, b, c, d, x[15], 9)
|
|
GGG128(d, a, b, c, x[ 5], 7)
|
|
GGG128(c, d, a, b, x[ 1], 15)
|
|
GGG128(b, c, d, a, x[ 3], 11)
|
|
GGG128(a, b, c, d, x[ 7], 8)
|
|
GGG128(d, a, b, c, x[14], 6)
|
|
GGG128(c, d, a, b, x[ 6], 6)
|
|
GGG128(b, c, d, a, x[ 9], 14)
|
|
GGG128(a, b, c, d, x[11], 12)
|
|
GGG128(d, a, b, c, x[ 8], 13)
|
|
GGG128(c, d, a, b, x[12], 5)
|
|
GGG128(b, c, d, a, x[ 2], 14)
|
|
GGG128(a, b, c, d, x[10], 13)
|
|
GGG128(d, a, b, c, x[ 0], 13)
|
|
GGG128(c, d, a, b, x[ 4], 7)
|
|
GGG128(b, c, d, a, x[13], 5)
|
|
|
|
template RROUND128N4(a, b, c, d, x): void =
|
|
FFF128(a, b, c, d, x[ 8], 15)
|
|
FFF128(d, a, b, c, x[ 6], 5)
|
|
FFF128(c, d, a, b, x[ 4], 8)
|
|
FFF128(b, c, d, a, x[ 1], 11)
|
|
FFF128(a, b, c, d, x[ 3], 14)
|
|
FFF128(d, a, b, c, x[11], 14)
|
|
FFF128(c, d, a, b, x[15], 6)
|
|
FFF128(b, c, d, a, x[ 0], 14)
|
|
FFF128(a, b, c, d, x[ 5], 6)
|
|
FFF128(d, a, b, c, x[12], 9)
|
|
FFF128(c, d, a, b, x[ 2], 12)
|
|
FFF128(b, c, d, a, x[13], 9)
|
|
FFF128(a, b, c, d, x[ 9], 12)
|
|
FFF128(d, a, b, c, x[ 7], 5)
|
|
FFF128(c, d, a, b, x[10], 15)
|
|
FFF128(b, c, d, a, x[14], 8)
|
|
|
|
template LROUND160N1(a, b, c, d, e, x): void =
|
|
FF160(a, b, c, d, e, x[ 0], 11)
|
|
FF160(e, a, b, c, d, x[ 1], 14)
|
|
FF160(d, e, a, b, c, x[ 2], 15)
|
|
FF160(c, d, e, a, b, x[ 3], 12)
|
|
FF160(b, c, d, e, a, x[ 4], 5)
|
|
FF160(a, b, c, d, e, x[ 5], 8)
|
|
FF160(e, a, b, c, d, x[ 6], 7)
|
|
FF160(d, e, a, b, c, x[ 7], 9)
|
|
FF160(c, d, e, a, b, x[ 8], 11)
|
|
FF160(b, c, d, e, a, x[ 9], 13)
|
|
FF160(a, b, c, d, e, x[10], 14)
|
|
FF160(e, a, b, c, d, x[11], 15)
|
|
FF160(d, e, a, b, c, x[12], 6)
|
|
FF160(c, d, e, a, b, x[13], 7)
|
|
FF160(b, c, d, e, a, x[14], 9)
|
|
FF160(a, b, c, d, e, x[15], 8)
|
|
|
|
template LROUND160N2(a, b, c, d, e, x): void =
|
|
GG160(e, a, b, c, d, x[ 7], 7)
|
|
GG160(d, e, a, b, c, x[ 4], 6)
|
|
GG160(c, d, e, a, b, x[13], 8)
|
|
GG160(b, c, d, e, a, x[ 1], 13)
|
|
GG160(a, b, c, d, e, x[10], 11)
|
|
GG160(e, a, b, c, d, x[ 6], 9)
|
|
GG160(d, e, a, b, c, x[15], 7)
|
|
GG160(c, d, e, a, b, x[ 3], 15)
|
|
GG160(b, c, d, e, a, x[12], 7)
|
|
GG160(a, b, c, d, e, x[ 0], 12)
|
|
GG160(e, a, b, c, d, x[ 9], 15)
|
|
GG160(d, e, a, b, c, x[ 5], 9)
|
|
GG160(c, d, e, a, b, x[ 2], 11)
|
|
GG160(b, c, d, e, a, x[14], 7)
|
|
GG160(a, b, c, d, e, x[11], 13)
|
|
GG160(e, a, b, c, d, x[ 8], 12)
|
|
|
|
template LROUND160N3(a, b, c, d, e, x): void =
|
|
HH160(d, e, a, b, c, x[ 3], 11)
|
|
HH160(c, d, e, a, b, x[10], 13)
|
|
HH160(b, c, d, e, a, x[14], 6)
|
|
HH160(a, b, c, d, e, x[ 4], 7)
|
|
HH160(e, a, b, c, d, x[ 9], 14)
|
|
HH160(d, e, a, b, c, x[15], 9)
|
|
HH160(c, d, e, a, b, x[ 8], 13)
|
|
HH160(b, c, d, e, a, x[ 1], 15)
|
|
HH160(a, b, c, d, e, x[ 2], 14)
|
|
HH160(e, a, b, c, d, x[ 7], 8)
|
|
HH160(d, e, a, b, c, x[ 0], 13)
|
|
HH160(c, d, e, a, b, x[ 6], 6)
|
|
HH160(b, c, d, e, a, x[13], 5)
|
|
HH160(a, b, c, d, e, x[11], 12)
|
|
HH160(e, a, b, c, d, x[ 5], 7)
|
|
HH160(d, e, a, b, c, x[12], 5)
|
|
|
|
template LROUND160N4(a, b, c, d, e, x): void =
|
|
II160(c, d, e, a, b, x[ 1], 11)
|
|
II160(b, c, d, e, a, x[ 9], 12)
|
|
II160(a, b, c, d, e, x[11], 14)
|
|
II160(e, a, b, c, d, x[10], 15)
|
|
II160(d, e, a, b, c, x[ 0], 14)
|
|
II160(c, d, e, a, b, x[ 8], 15)
|
|
II160(b, c, d, e, a, x[12], 9)
|
|
II160(a, b, c, d, e, x[ 4], 8)
|
|
II160(e, a, b, c, d, x[13], 9)
|
|
II160(d, e, a, b, c, x[ 3], 14)
|
|
II160(c, d, e, a, b, x[ 7], 5)
|
|
II160(b, c, d, e, a, x[15], 6)
|
|
II160(a, b, c, d, e, x[14], 8)
|
|
II160(e, a, b, c, d, x[ 5], 6)
|
|
II160(d, e, a, b, c, x[ 6], 5)
|
|
II160(c, d, e, a, b, x[ 2], 12)
|
|
|
|
template LROUND160N5(a, b, c, d, e, x): void =
|
|
JJ160(b, c, d, e, a, x[ 4], 9)
|
|
JJ160(a, b, c, d, e, x[ 0], 15)
|
|
JJ160(e, a, b, c, d, x[ 5], 5)
|
|
JJ160(d, e, a, b, c, x[ 9], 11)
|
|
JJ160(c, d, e, a, b, x[ 7], 6)
|
|
JJ160(b, c, d, e, a, x[12], 8)
|
|
JJ160(a, b, c, d, e, x[ 2], 13)
|
|
JJ160(e, a, b, c, d, x[10], 12)
|
|
JJ160(d, e, a, b, c, x[14], 5)
|
|
JJ160(c, d, e, a, b, x[ 1], 12)
|
|
JJ160(b, c, d, e, a, x[ 3], 13)
|
|
JJ160(a, b, c, d, e, x[ 8], 14)
|
|
JJ160(e, a, b, c, d, x[11], 11)
|
|
JJ160(d, e, a, b, c, x[ 6], 8)
|
|
JJ160(c, d, e, a, b, x[15], 5)
|
|
JJ160(b, c, d, e, a, x[13], 6)
|
|
|
|
template RROUND160N1(a, b, c, d, e, x): void =
|
|
JJJ160(a, b, c, d, e, x[ 5], 8)
|
|
JJJ160(e, a, b, c, d, x[14], 9)
|
|
JJJ160(d, e, a, b, c, x[ 7], 9)
|
|
JJJ160(c, d, e, a, b, x[ 0], 11)
|
|
JJJ160(b, c, d, e, a, x[ 9], 13)
|
|
JJJ160(a, b, c, d, e, x[ 2], 15)
|
|
JJJ160(e, a, b, c, d, x[11], 15)
|
|
JJJ160(d, e, a, b, c, x[ 4], 5)
|
|
JJJ160(c, d, e, a, b, x[13], 7)
|
|
JJJ160(b, c, d, e, a, x[ 6], 7)
|
|
JJJ160(a, b, c, d, e, x[15], 8)
|
|
JJJ160(e, a, b, c, d, x[ 8], 11)
|
|
JJJ160(d, e, a, b, c, x[ 1], 14)
|
|
JJJ160(c, d, e, a, b, x[10], 14)
|
|
JJJ160(b, c, d, e, a, x[ 3], 12)
|
|
JJJ160(a, b, c, d, e, x[12], 6)
|
|
|
|
template RROUND160N2(a, b, c, d, e, x): void =
|
|
III160(e, a, b, c, d, x[ 6], 9)
|
|
III160(d, e, a, b, c, x[11], 13)
|
|
III160(c, d, e, a, b, x[ 3], 15)
|
|
III160(b, c, d, e, a, x[ 7], 7)
|
|
III160(a, b, c, d, e, x[ 0], 12)
|
|
III160(e, a, b, c, d, x[13], 8)
|
|
III160(d, e, a, b, c, x[ 5], 9)
|
|
III160(c, d, e, a, b, x[10], 11)
|
|
III160(b, c, d, e, a, x[14], 7)
|
|
III160(a, b, c, d, e, x[15], 7)
|
|
III160(e, a, b, c, d, x[ 8], 12)
|
|
III160(d, e, a, b, c, x[12], 7)
|
|
III160(c, d, e, a, b, x[ 4], 6)
|
|
III160(b, c, d, e, a, x[ 9], 15)
|
|
III160(a, b, c, d, e, x[ 1], 13)
|
|
III160(e, a, b, c, d, x[ 2], 11)
|
|
|
|
template RROUND160N3(a, b, c, d, e, x): void =
|
|
HHH160(d, e, a, b, c, x[15], 9)
|
|
HHH160(c, d, e, a, b, x[ 5], 7)
|
|
HHH160(b, c, d, e, a, x[ 1], 15)
|
|
HHH160(a, b, c, d, e, x[ 3], 11)
|
|
HHH160(e, a, b, c, d, x[ 7], 8)
|
|
HHH160(d, e, a, b, c, x[14], 6)
|
|
HHH160(c, d, e, a, b, x[ 6], 6)
|
|
HHH160(b, c, d, e, a, x[ 9], 14)
|
|
HHH160(a, b, c, d, e, x[11], 12)
|
|
HHH160(e, a, b, c, d, x[ 8], 13)
|
|
HHH160(d, e, a, b, c, x[12], 5)
|
|
HHH160(c, d, e, a, b, x[ 2], 14)
|
|
HHH160(b, c, d, e, a, x[10], 13)
|
|
HHH160(a, b, c, d, e, x[ 0], 13)
|
|
HHH160(e, a, b, c, d, x[ 4], 7)
|
|
HHH160(d, e, a, b, c, x[13], 5)
|
|
|
|
template RROUND160N4(a, b, c, d, e, x): void =
|
|
GGG160(c, d, e, a, b, x[ 8], 15)
|
|
GGG160(b, c, d, e, a, x[ 6], 5)
|
|
GGG160(a, b, c, d, e, x[ 4], 8)
|
|
GGG160(e, a, b, c, d, x[ 1], 11)
|
|
GGG160(d, e, a, b, c, x[ 3], 14)
|
|
GGG160(c, d, e, a, b, x[11], 14)
|
|
GGG160(b, c, d, e, a, x[15], 6)
|
|
GGG160(a, b, c, d, e, x[ 0], 14)
|
|
GGG160(e, a, b, c, d, x[ 5], 6)
|
|
GGG160(d, e, a, b, c, x[12], 9)
|
|
GGG160(c, d, e, a, b, x[ 2], 12)
|
|
GGG160(b, c, d, e, a, x[13], 9)
|
|
GGG160(a, b, c, d, e, x[ 9], 12)
|
|
GGG160(e, a, b, c, d, x[ 7], 5)
|
|
GGG160(d, e, a, b, c, x[10], 15)
|
|
GGG160(c, d, e, a, b, x[14], 8)
|
|
|
|
template RROUND160N5(a, b, c, d, e, x): void =
|
|
FFF160(b, c, d, e, a, x[12] , 8)
|
|
FFF160(a, b, c, d, e, x[15] , 5)
|
|
FFF160(e, a, b, c, d, x[10] , 12)
|
|
FFF160(d, e, a, b, c, x[ 4] , 9)
|
|
FFF160(c, d, e, a, b, x[ 1] , 12)
|
|
FFF160(b, c, d, e, a, x[ 5] , 5)
|
|
FFF160(a, b, c, d, e, x[ 8] , 14)
|
|
FFF160(e, a, b, c, d, x[ 7] , 6)
|
|
FFF160(d, e, a, b, c, x[ 6] , 8)
|
|
FFF160(c, d, e, a, b, x[ 2] , 13)
|
|
FFF160(b, c, d, e, a, x[13] , 6)
|
|
FFF160(a, b, c, d, e, x[14] , 5)
|
|
FFF160(e, a, b, c, d, x[ 0] , 15)
|
|
FFF160(d, e, a, b, c, x[ 3] , 13)
|
|
FFF160(c, d, e, a, b, x[ 9] , 11)
|
|
FFF160(b, c, d, e, a, x[11] , 11)
|
|
|
|
proc ripemd128Transform(state: var array[4, uint32], data: openarray[byte]) =
|
|
var
|
|
aa = state[0]
|
|
bb = state[1]
|
|
cc = state[2]
|
|
dd = state[3]
|
|
aaa = state[0]
|
|
bbb = state[1]
|
|
ccc = state[2]
|
|
ddd = state[3]
|
|
X {.noinit.}: array[16, uint32]
|
|
|
|
X[0] = leLoad32(data, 0); X[1] = leLoad32(data, 4)
|
|
X[2] = leLoad32(data, 8); X[3] = leLoad32(data, 12)
|
|
X[4] = leLoad32(data, 16); X[5] = leLoad32(data, 20)
|
|
X[6] = leLoad32(data, 24); X[7] = leLoad32(data, 28)
|
|
X[8] = leLoad32(data, 32); X[9] = leLoad32(data, 36)
|
|
X[10] = leLoad32(data, 40); X[11] = leLoad32(data, 44)
|
|
X[12] = leLoad32(data, 48); X[13] = leLoad32(data, 52)
|
|
X[14] = leLoad32(data, 56); X[15] = leLoad32(data, 60)
|
|
|
|
LROUND128N1(aa, bb, cc, dd, X)
|
|
LROUND128N2(aa, bb, cc, dd, X)
|
|
LROUND128N3(aa, bb, cc, dd, X)
|
|
LROUND128N4(aa, bb, cc, dd, X)
|
|
RROUND128N1(aaa, bbb, ccc, ddd, X)
|
|
RROUND128N2(aaa, bbb, ccc, ddd, X)
|
|
RROUND128N3(aaa, bbb, ccc, ddd, X)
|
|
RROUND128N4(aaa, bbb, ccc, ddd, X)
|
|
|
|
# combine results
|
|
ddd = ddd + cc + state[1]
|
|
state[1] = state[2] + dd + aaa
|
|
state[2] = state[3] + aa + bbb
|
|
state[3] = state[0] + bb + ccc
|
|
state[0] = ddd
|
|
|
|
proc ripemd256Transform(state: var array[8, uint32], data: openarray[byte]) =
|
|
var
|
|
aa = state[0]
|
|
bb = state[1]
|
|
cc = state[2]
|
|
dd = state[3]
|
|
aaa = state[4]
|
|
bbb = state[5]
|
|
ccc = state[6]
|
|
ddd = state[7]
|
|
X {.noinit.}: array[16, uint32]
|
|
|
|
X[0] = leLoad32(data, 0); X[1] = leLoad32(data, 4)
|
|
X[2] = leLoad32(data, 8); X[3] = leLoad32(data, 12)
|
|
X[4] = leLoad32(data, 16); X[5] = leLoad32(data, 20)
|
|
X[6] = leLoad32(data, 24); X[7] = leLoad32(data, 28)
|
|
X[8] = leLoad32(data, 32); X[9] = leLoad32(data, 36)
|
|
X[10] = leLoad32(data, 40); X[11] = leLoad32(data, 44)
|
|
X[12] = leLoad32(data, 48); X[13] = leLoad32(data, 52)
|
|
X[14] = leLoad32(data, 56); X[15] = leLoad32(data, 60)
|
|
|
|
LROUND128N1(aa, bb, cc, dd, X)
|
|
RROUND128N1(aaa, bbb, ccc, ddd, X)
|
|
swap(aa, aaa)
|
|
LROUND128N2(aa, bb, cc, dd, X)
|
|
RROUND128N2(aaa, bbb, ccc, ddd, X)
|
|
swap(bb, bbb)
|
|
LROUND128N3(aa, bb, cc, dd, X)
|
|
RROUND128N3(aaa, bbb, ccc, ddd, X)
|
|
swap(cc, ccc)
|
|
LROUND128N4(aa, bb, cc, dd, X)
|
|
RROUND128N4(aaa, bbb, ccc, ddd, X)
|
|
swap(dd, ddd)
|
|
|
|
# combine results
|
|
state[0] = state[0] + aa
|
|
state[1] = state[1] + bb
|
|
state[2] = state[2] + cc
|
|
state[3] = state[3] + dd
|
|
state[4] = state[4] + aaa
|
|
state[5] = state[5] + bbb
|
|
state[6] = state[6] + ccc
|
|
state[7] = state[7] + ddd
|
|
|
|
proc ripemd160Transform(state: var array[5, uint32],
|
|
data: openarray[byte]) {.inline.} =
|
|
var
|
|
aa = state[0]
|
|
bb = state[1]
|
|
cc = state[2]
|
|
dd = state[3]
|
|
ee = state[4]
|
|
aaa = state[0]
|
|
bbb = state[1]
|
|
ccc = state[2]
|
|
ddd = state[3]
|
|
eee = state[4]
|
|
X {.noinit.}: array[16, uint32]
|
|
|
|
X[0] = leLoad32(data, 0); X[1] = leLoad32(data, 4)
|
|
X[2] = leLoad32(data, 8); X[3] = leLoad32(data, 12)
|
|
X[4] = leLoad32(data, 16); X[5] = leLoad32(data, 20)
|
|
X[6] = leLoad32(data, 24); X[7] = leLoad32(data, 28)
|
|
X[8] = leLoad32(data, 32); X[9] = leLoad32(data, 36)
|
|
X[10] = leLoad32(data, 40); X[11] = leLoad32(data, 44)
|
|
X[12] = leLoad32(data, 48); X[13] = leLoad32(data, 52)
|
|
X[14] = leLoad32(data, 56); X[15] = leLoad32(data, 60)
|
|
|
|
LROUND160N1(aa, bb, cc, dd, ee, X)
|
|
LROUND160N2(aa, bb, cc, dd, ee, X)
|
|
LROUND160N3(aa, bb, cc, dd, ee, X)
|
|
LROUND160N4(aa, bb, cc, dd, ee, X)
|
|
LROUND160N5(aa, bb, cc, dd, ee, X)
|
|
RROUND160N1(aaa, bbb, ccc, ddd, eee, X)
|
|
RROUND160N2(aaa, bbb, ccc, ddd, eee, X)
|
|
RROUND160N3(aaa, bbb, ccc, ddd, eee, X)
|
|
RROUND160N4(aaa, bbb, ccc, ddd, eee, X)
|
|
RROUND160N5(aaa, bbb, ccc, ddd, eee, X)
|
|
|
|
# combine results
|
|
ddd = ddd + cc + state[1]
|
|
state[1] = state[2] + dd + eee
|
|
state[2] = state[3] + ee + aaa
|
|
state[3] = state[4] + aa + bbb
|
|
state[4] = state[0] + bb + ccc
|
|
state[0] = ddd
|
|
|
|
proc ripemd320Transform(state: var array[10, uint32],
|
|
data: openarray[byte]) {.inline.} =
|
|
var
|
|
aa = state[0]
|
|
bb = state[1]
|
|
cc = state[2]
|
|
dd = state[3]
|
|
ee = state[4]
|
|
aaa = state[5]
|
|
bbb = state[6]
|
|
ccc = state[7]
|
|
ddd = state[8]
|
|
eee = state[9]
|
|
X {.noinit.}: array[16, uint32]
|
|
|
|
X[0] = leLoad32(data, 0); X[1] = leLoad32(data, 4)
|
|
X[2] = leLoad32(data, 8); X[3] = leLoad32(data, 12)
|
|
X[4] = leLoad32(data, 16); X[5] = leLoad32(data, 20)
|
|
X[6] = leLoad32(data, 24); X[7] = leLoad32(data, 28)
|
|
X[8] = leLoad32(data, 32); X[9] = leLoad32(data, 36)
|
|
X[10] = leLoad32(data, 40); X[11] = leLoad32(data, 44)
|
|
X[12] = leLoad32(data, 48); X[13] = leLoad32(data, 52)
|
|
X[14] = leLoad32(data, 56); X[15] = leLoad32(data, 60)
|
|
|
|
LROUND160N1(aa, bb, cc, dd, ee, X)
|
|
RROUND160N1(aaa, bbb, ccc, ddd, eee, X)
|
|
swap(aa, aaa)
|
|
LROUND160N2(aa, bb, cc, dd, ee, X)
|
|
RROUND160N2(aaa, bbb, ccc, ddd, eee, X)
|
|
swap(bb, bbb)
|
|
LROUND160N3(aa, bb, cc, dd, ee, X)
|
|
RROUND160N3(aaa, bbb, ccc, ddd, eee, X)
|
|
swap(cc, ccc)
|
|
LROUND160N4(aa, bb, cc, dd, ee, X)
|
|
RROUND160N4(aaa, bbb, ccc, ddd, eee, X)
|
|
swap(dd, ddd)
|
|
LROUND160N5(aa, bb, cc, dd, ee, X)
|
|
RROUND160N5(aaa, bbb, ccc, ddd, eee, X)
|
|
swap(ee, eee)
|
|
|
|
# combine results
|
|
state[0] = state[0] + aa
|
|
state[1] = state[1] + bb
|
|
state[2] = state[2] + cc
|
|
state[3] = state[3] + dd
|
|
state[4] = state[4] + ee
|
|
state[5] = state[5] + aaa
|
|
state[6] = state[6] + bbb
|
|
state[7] = state[7] + ccc
|
|
state[8] = state[8] + ddd
|
|
state[9] = state[9] + eee
|
|
|
|
template sizeDigest*(ctx: RipemdContext): uint =
|
|
(ctx.bits div 8)
|
|
|
|
template sizeBlock*(ctx: RipemdContext): uint =
|
|
(64)
|
|
|
|
template sizeDigest*(r: typedesc[ripemd]): int =
|
|
when r is ripemd128:
|
|
(16)
|
|
elif r is ripemd160:
|
|
(20)
|
|
elif r is ripemd256:
|
|
(32)
|
|
elif r is ripemd320:
|
|
(40)
|
|
|
|
template sizeBlock*(r: typedesc[ripemd]): int =
|
|
(64)
|
|
|
|
proc init*(ctx: var RipemdContext) {.inline.} =
|
|
ctx.count[0] = 0
|
|
ctx.count[1] = 0
|
|
|
|
when nimvm:
|
|
for i in 0 ..< len(ctx.buffer):
|
|
ctx.buffer[i] = 0'u8
|
|
else:
|
|
zeroMem(addr ctx.buffer[0], sizeof(byte) * 64)
|
|
|
|
when ctx.bits == 128:
|
|
ctx.state[0] = 0x67452301'u32
|
|
ctx.state[1] = 0xEFCDAB89'u32
|
|
ctx.state[2] = 0x98BADCFE'u32
|
|
ctx.state[3] = 0x10325476'u32
|
|
elif ctx.bits == 160:
|
|
ctx.state[0] = 0x67452301'u32
|
|
ctx.state[1] = 0xEFCDAB89'u32
|
|
ctx.state[2] = 0x98BADCFE'u32
|
|
ctx.state[3] = 0x10325476'u32
|
|
ctx.state[4] = 0xC3D2E1F0'u32
|
|
elif ctx.bits == 256:
|
|
ctx.state[0] = 0x67452301'u32
|
|
ctx.state[1] = 0xEFCDAB89'u32
|
|
ctx.state[2] = 0x98BADCFE'u32
|
|
ctx.state[3] = 0x10325476'u32
|
|
ctx.state[4] = 0x76543210'u32
|
|
ctx.state[5] = 0xFEDCBA98'u32
|
|
ctx.state[6] = 0x89ABCDEF'u32
|
|
ctx.state[7] = 0x01234567'u32
|
|
elif ctx.bits == 320:
|
|
ctx.state[0] = 0x67452301'u32
|
|
ctx.state[1] = 0xEFCDAB89'u32
|
|
ctx.state[2] = 0x98BADCFE'u32
|
|
ctx.state[3] = 0x10325476'u32
|
|
ctx.state[4] = 0xC3D2E1F0'u32
|
|
ctx.state[5] = 0x76543210'u32
|
|
ctx.state[6] = 0xFEDCBA98'u32
|
|
ctx.state[7] = 0x89ABCDEF'u32
|
|
ctx.state[8] = 0x01234567'u32
|
|
ctx.state[9] = 0x3C2D1E0F'u32
|
|
|
|
proc clear*(ctx: var RipemdContext) {.inline.} =
|
|
when nimvm:
|
|
ctx.count[0] = 0x00'u32
|
|
ctx.count[1] = 0x00'u32
|
|
when ctx.bits == 128:
|
|
ctx.state[0] = 0x00'u32
|
|
ctx.state[1] = 0x00'u32
|
|
ctx.state[2] = 0x00'u32
|
|
ctx.state[3] = 0x00'u32
|
|
elif ctx.bits == 160:
|
|
ctx.state[0] = 0x00'u32
|
|
ctx.state[1] = 0x00'u32
|
|
ctx.state[2] = 0x00'u32
|
|
ctx.state[3] = 0x00'u32
|
|
ctx.state[4] = 0x00'u32
|
|
elif ctx.bits == 256:
|
|
ctx.state[0] = 0x00'u32
|
|
ctx.state[1] = 0x00'u32
|
|
ctx.state[2] = 0x00'u32
|
|
ctx.state[3] = 0x00'u32
|
|
ctx.state[4] = 0x00'u32
|
|
ctx.state[5] = 0x00'u32
|
|
ctx.state[6] = 0x00'u32
|
|
ctx.state[7] = 0x00'u32
|
|
elif ctx.bits == 320:
|
|
ctx.state[0] = 0x00'u32
|
|
ctx.state[1] = 0x00'u32
|
|
ctx.state[2] = 0x00'u32
|
|
ctx.state[3] = 0x00'u32
|
|
ctx.state[4] = 0x00'u32
|
|
ctx.state[5] = 0x00'u32
|
|
ctx.state[6] = 0x00'u32
|
|
ctx.state[7] = 0x00'u32
|
|
ctx.state[8] = 0x00'u32
|
|
ctx.state[9] = 0x00'u32
|
|
for i in 0 ..< 64:
|
|
ctx.buffer[i] = 0x00'u8
|
|
else:
|
|
burnMem(ctx)
|
|
|
|
proc reset*(ctx: var RipemdContext) {.inline.} =
|
|
init(ctx)
|
|
|
|
proc update*[T: bchar](ctx: var RipemdContext, data: openarray[T]) {.inline.} =
|
|
var pos = 0
|
|
var length = len(data)
|
|
|
|
while length > 0:
|
|
let offset = int(ctx.count[0] and 0x3F)
|
|
let size = min(64 - offset, length)
|
|
copyMem(ctx.buffer, offset, data, pos, size)
|
|
pos = pos + size
|
|
length = length - size
|
|
ctx.count[0] = ctx.count[0] + uint32(size)
|
|
if ctx.count[0] < uint32(size):
|
|
ctx.count[1] = ctx.count[1] + 1'u32
|
|
if (ctx.count[0] and 0x3F'u32) == 0:
|
|
when ctx.bits == 128:
|
|
ripemd128Transform(ctx.state, ctx.buffer)
|
|
elif ctx.bits == 160:
|
|
ripemd160Transform(ctx.state, ctx.buffer)
|
|
elif ctx.bits == 256:
|
|
ripemd256Transform(ctx.state, ctx.buffer)
|
|
elif ctx.bits == 320:
|
|
ripemd320Transform(ctx.state, ctx.buffer)
|
|
|
|
proc update*(ctx: var RipemdContext, pbytes: ptr byte,
|
|
nbytes: uint) {.inline.} =
|
|
var p = cast[ptr array[0, byte]](pbytes)
|
|
ctx.update(toOpenArray(p[], 0, int(nbytes) - 1))
|
|
|
|
proc finalize(ctx: var RipemdContext) {.inline.} =
|
|
let size = int(ctx.count[0] and 0x3F'u32)
|
|
when nimvm:
|
|
for i in size ..< 64:
|
|
ctx.buffer[i] = 0x00'u8
|
|
else:
|
|
zeroMem(addr(ctx.buffer[size]), 64 - size)
|
|
|
|
ctx.buffer[size] = 0x80
|
|
if size > 55:
|
|
when ctx.bits == 128:
|
|
ripemd128Transform(ctx.state, ctx.buffer)
|
|
elif ctx.bits == 160:
|
|
ripemd160Transform(ctx.state, ctx.buffer)
|
|
elif ctx.bits == 256:
|
|
ripemd256Transform(ctx.state, ctx.buffer)
|
|
elif ctx.bits == 320:
|
|
ripemd320Transform(ctx.state, ctx.buffer)
|
|
when nimvm:
|
|
for i in 0 ..< 64:
|
|
ctx.buffer[i] = 0x00'u8
|
|
else:
|
|
zeroMem(addr(ctx.buffer[0]), 64)
|
|
|
|
leStore32(ctx.buffer, 56, (ctx.count[0]) shl 3)
|
|
leStore32(ctx.buffer, 60, ((ctx.count[0]) shr 29) or (ctx.count[1] shl 3))
|
|
|
|
when ctx.bits == 128:
|
|
ripemd128Transform(ctx.state, ctx.buffer)
|
|
elif ctx.bits == 160:
|
|
ripemd160Transform(ctx.state, ctx.buffer)
|
|
elif ctx.bits == 256:
|
|
ripemd256Transform(ctx.state, ctx.buffer)
|
|
elif ctx.bits == 320:
|
|
ripemd320Transform(ctx.state, ctx.buffer)
|
|
|
|
proc finish*(ctx: var RipemdContext,
|
|
data: var openarray[byte]): uint {.inline, discardable.} =
|
|
result = 0
|
|
finalize(ctx)
|
|
when ctx.bits == 128:
|
|
if len(data) >= 16:
|
|
result = sizeDigest(ctx)
|
|
leStore32(data, 0, ctx.state[0])
|
|
leStore32(data, 4, ctx.state[1])
|
|
leStore32(data, 8, ctx.state[2])
|
|
leStore32(data, 12, ctx.state[3])
|
|
elif ctx.bits == 160:
|
|
if len(data) >= 20:
|
|
result = sizeDigest(ctx)
|
|
leStore32(data, 0, ctx.state[0])
|
|
leStore32(data, 4, ctx.state[1])
|
|
leStore32(data, 8, ctx.state[2])
|
|
leStore32(data, 12, ctx.state[3])
|
|
leStore32(data, 16, ctx.state[4])
|
|
elif ctx.bits == 256:
|
|
if len(data) >= 32:
|
|
result = sizeDigest(ctx)
|
|
leStore32(data, 0, ctx.state[0])
|
|
leStore32(data, 4, ctx.state[1])
|
|
leStore32(data, 8, ctx.state[2])
|
|
leStore32(data, 12, ctx.state[3])
|
|
leStore32(data, 16, ctx.state[4])
|
|
leStore32(data, 20, ctx.state[5])
|
|
leStore32(data, 24, ctx.state[6])
|
|
leStore32(data, 28, ctx.state[7])
|
|
elif ctx.bits == 320:
|
|
if len(data) >= 40:
|
|
result = sizeDigest(ctx)
|
|
leStore32(data, 0, ctx.state[0])
|
|
leStore32(data, 4, ctx.state[1])
|
|
leStore32(data, 8, ctx.state[2])
|
|
leStore32(data, 12, ctx.state[3])
|
|
leStore32(data, 16, ctx.state[4])
|
|
leStore32(data, 20, ctx.state[5])
|
|
leStore32(data, 24, ctx.state[6])
|
|
leStore32(data, 28, ctx.state[7])
|
|
leStore32(data, 32, ctx.state[8])
|
|
leStore32(data, 36, ctx.state[9])
|
|
|
|
proc finish*(ctx: var RipemdContext, pbytes: ptr byte,
|
|
nbytes: uint): uint {.inline.} =
|
|
var ptrarr = cast[ptr array[0, byte]](pbytes)
|
|
result = ctx.finish(ptrarr[].toOpenArray(0, int(nbytes) - 1))
|
|
|
|
proc finish*(ctx: var RipemdContext): MDigest[ctx.bits] =
|
|
discard finish(ctx, result.data)
|