Compare commits
4 Commits
85ab748c07
...
17b765b13c
| Author | SHA1 | Date | |
|---|---|---|---|
|
17b765b13c
|
|||
|
b41debf948
|
|||
|
6dc3cf3b87
|
|||
|
16390b0308
|
@@ -43,12 +43,25 @@ object `Blake-224` : HashFunction() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun hash(value: UByteArray): UByteArray {
|
override fun hash(value: UByteArray): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
var t = 0U
|
var t = 0U
|
||||||
val l = value.size.toULong() * 8UL
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(64) { it.toUByteArray() }
|
||||||
|
for (block in blocks) {
|
||||||
|
t += minOf(l - t, 512UL).toUInt()
|
||||||
|
compress(h, block, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.sliceArray(0..6).toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
add(0x80U)
|
add(0x80U)
|
||||||
while (size % 64 != 56) {
|
while (size % 64 != 56) {
|
||||||
@@ -56,56 +69,39 @@ object `Blake-224` : HashFunction() {
|
|||||||
}
|
}
|
||||||
addAll(l.toUByteArray())
|
addAll(l.toUByteArray())
|
||||||
}.toUByteArray()
|
}.toUByteArray()
|
||||||
|
|
||||||
// compress
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(64) { it.toUByteArray() }
|
|
||||||
for (block in blocks) {
|
|
||||||
t += minOf(l - t, 512UL).toUInt()
|
|
||||||
|
|
||||||
val m = block.toUIntArray()
|
|
||||||
compress(h, m, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.sliceArray(0..6).toUByteArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compress(
|
private fun compress(
|
||||||
h: UIntArray,
|
h: UIntArray,
|
||||||
m: UIntArray,
|
block: UByteArray,
|
||||||
t: UInt,
|
t: UInt,
|
||||||
) {
|
) {
|
||||||
// initialization
|
val m = block.toUIntArray()
|
||||||
val v = UIntArray(16)
|
val v = UIntArray(16)
|
||||||
for (i in 0..<8) v[i] = h[i]
|
for (i in 0..<8) v[i] = h[i]
|
||||||
for (i in 0..<4) v[i + 8] = c[i]
|
for (i in 0..<4) v[i + 8] = c[i]
|
||||||
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
|
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
|
||||||
for (i in 0..<2) v[i + 14] = c[i + 6]
|
for (i in 0..<2) v[i + 14] = c[i + 6]
|
||||||
|
|
||||||
// rounds
|
repeat(14) { r ->
|
||||||
for (r in 0..<14) {
|
|
||||||
val s = sigma[r % 10]
|
val s = sigma[r % 10]
|
||||||
|
|
||||||
// column
|
|
||||||
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
|
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
|
||||||
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
|
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
|
||||||
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
|
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
|
||||||
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
|
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
|
||||||
|
|
||||||
// diagonal
|
|
||||||
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
|
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
|
||||||
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
|
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
|
||||||
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
|
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
|
||||||
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
|
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalization
|
|
||||||
for (i in 0..7) {
|
for (i in 0..7) {
|
||||||
h[i] = h[i] xor v[i] xor v[i + 8]
|
h[i] = h[i] xor v[i] xor v[i + 8]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// round function
|
|
||||||
private fun g(
|
private fun g(
|
||||||
v: UIntArray,
|
v: UIntArray,
|
||||||
a: Int,
|
a: Int,
|
||||||
|
|||||||
@@ -43,12 +43,25 @@ object `Blake-256` : HashFunction() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun hash(value: UByteArray): UByteArray {
|
override fun hash(value: UByteArray): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
var t = 0U
|
var t = 0U
|
||||||
val l = value.size.toULong() * 8UL
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(64) { it.toUByteArray() }
|
||||||
|
for (block in blocks) {
|
||||||
|
t += minOf(l - t, 512UL).toUInt()
|
||||||
|
compress(h, block, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
add(0x80U)
|
add(0x80U)
|
||||||
while (size % 64 != 55) {
|
while (size % 64 != 55) {
|
||||||
@@ -57,56 +70,39 @@ object `Blake-256` : HashFunction() {
|
|||||||
add(0x01U)
|
add(0x01U)
|
||||||
addAll(l.toUByteArray())
|
addAll(l.toUByteArray())
|
||||||
}.toUByteArray()
|
}.toUByteArray()
|
||||||
|
|
||||||
// compress
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(64) { it.toUByteArray() }
|
|
||||||
for (block in blocks) {
|
|
||||||
t += minOf(l - t, 512UL).toUInt()
|
|
||||||
|
|
||||||
val m = block.toUIntArray()
|
|
||||||
compress(h, m, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.toUByteArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compress(
|
private fun compress(
|
||||||
h: UIntArray,
|
h: UIntArray,
|
||||||
m: UIntArray,
|
block: UByteArray,
|
||||||
t: UInt,
|
t: UInt,
|
||||||
) {
|
) {
|
||||||
// initialization
|
val m = block.toUIntArray()
|
||||||
val v = UIntArray(16)
|
val v = UIntArray(16)
|
||||||
for (i in 0..<8) v[i] = h[i]
|
for (i in 0..<8) v[i] = h[i]
|
||||||
for (i in 0..<4) v[i + 8] = c[i]
|
for (i in 0..<4) v[i + 8] = c[i]
|
||||||
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
|
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
|
||||||
for (i in 0..<2) v[i + 14] = c[i + 6]
|
for (i in 0..<2) v[i + 14] = c[i + 6]
|
||||||
|
|
||||||
// rounds
|
repeat(14) { r ->
|
||||||
for (r in 0..<14) {
|
|
||||||
val s = sigma[r % 10]
|
val s = sigma[r % 10]
|
||||||
|
|
||||||
// column
|
|
||||||
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
|
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
|
||||||
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
|
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
|
||||||
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
|
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
|
||||||
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
|
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
|
||||||
|
|
||||||
// diagonal
|
|
||||||
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
|
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
|
||||||
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
|
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
|
||||||
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
|
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
|
||||||
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
|
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalization
|
|
||||||
for (i in 0..7) {
|
for (i in 0..7) {
|
||||||
h[i] = h[i] xor v[i] xor v[i + 8]
|
h[i] = h[i] xor v[i] xor v[i + 8]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// round function
|
|
||||||
private fun g(
|
private fun g(
|
||||||
v: UIntArray,
|
v: UIntArray,
|
||||||
a: Int,
|
a: Int,
|
||||||
|
|||||||
@@ -43,12 +43,25 @@ object `Blake-384` : HashFunction() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun hash(value: UByteArray): UByteArray {
|
override fun hash(value: UByteArray): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
var t = 0UL
|
var t = 0UL
|
||||||
val l = value.size.toULong() * 8UL
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(128) { it.toUByteArray() }
|
||||||
|
for (block in blocks) {
|
||||||
|
t += minOf(l - t, 1024UL)
|
||||||
|
compress(h, block, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.sliceArray(0..5).toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
add(0x80U)
|
add(0x80U)
|
||||||
while (size % 128 != 120) {
|
while (size % 128 != 120) {
|
||||||
@@ -56,56 +69,39 @@ object `Blake-384` : HashFunction() {
|
|||||||
}
|
}
|
||||||
addAll(l.toUByteArray())
|
addAll(l.toUByteArray())
|
||||||
}.toUByteArray()
|
}.toUByteArray()
|
||||||
|
|
||||||
// compress
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(128) { it.toUByteArray() }
|
|
||||||
for (block in blocks) {
|
|
||||||
t += minOf(l - t, 1024UL)
|
|
||||||
|
|
||||||
val m = block.toULongArray()
|
|
||||||
compress(h, m, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.sliceArray(0..5).toUByteArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compress(
|
private fun compress(
|
||||||
h: ULongArray,
|
h: ULongArray,
|
||||||
m: ULongArray,
|
block: UByteArray,
|
||||||
t: ULong,
|
t: ULong,
|
||||||
) {
|
) {
|
||||||
// initialization
|
val m = block.toULongArray()
|
||||||
val v = ULongArray(16)
|
val v = ULongArray(16)
|
||||||
for (i in 0..<8) v[i] = h[i]
|
for (i in 0..<8) v[i] = h[i]
|
||||||
for (i in 0..<4) v[i + 8] = c[i]
|
for (i in 0..<4) v[i + 8] = c[i]
|
||||||
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
|
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
|
||||||
for (i in 0..<2) v[i + 14] = c[i + 6]
|
for (i in 0..<2) v[i + 14] = c[i + 6]
|
||||||
|
|
||||||
// rounds
|
repeat(16) { r ->
|
||||||
for (r in 0..<16) {
|
|
||||||
val s = sigma[r % 10]
|
val s = sigma[r % 10]
|
||||||
|
|
||||||
// column
|
|
||||||
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
|
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
|
||||||
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
|
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
|
||||||
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
|
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
|
||||||
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
|
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
|
||||||
|
|
||||||
// diagonal
|
|
||||||
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
|
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
|
||||||
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
|
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
|
||||||
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
|
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
|
||||||
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
|
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalization
|
|
||||||
for (i in 0..7) {
|
for (i in 0..7) {
|
||||||
h[i] = h[i] xor v[i] xor v[i + 8]
|
h[i] = h[i] xor v[i] xor v[i + 8]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// round function
|
|
||||||
private fun g(
|
private fun g(
|
||||||
v: ULongArray,
|
v: ULongArray,
|
||||||
a: Int,
|
a: Int,
|
||||||
|
|||||||
@@ -43,12 +43,25 @@ object `Blake-512` : HashFunction() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun hash(value: UByteArray): UByteArray {
|
override fun hash(value: UByteArray): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
var t = 0UL
|
var t = 0UL
|
||||||
val l = value.size.toULong() * 8UL
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(128) { it.toUByteArray() }
|
||||||
|
for (block in blocks) {
|
||||||
|
t += minOf(l - t, 1024UL)
|
||||||
|
compress(h, block, t)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
add(0x80U)
|
add(0x80U)
|
||||||
while (size % 128 != 111) {
|
while (size % 128 != 111) {
|
||||||
@@ -58,56 +71,39 @@ object `Blake-512` : HashFunction() {
|
|||||||
repeat(8) { add(0x00U) }
|
repeat(8) { add(0x00U) }
|
||||||
addAll(l.toUByteArray())
|
addAll(l.toUByteArray())
|
||||||
}.toUByteArray()
|
}.toUByteArray()
|
||||||
|
|
||||||
// compress
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(128) { it.toUByteArray() }
|
|
||||||
for (block in blocks) {
|
|
||||||
t += minOf(l - t, 1024UL)
|
|
||||||
|
|
||||||
val m = block.toULongArray()
|
|
||||||
compress(h, m, t)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.toUByteArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compress(
|
private fun compress(
|
||||||
h: ULongArray,
|
h: ULongArray,
|
||||||
m: ULongArray,
|
block: UByteArray,
|
||||||
t: ULong,
|
t: ULong,
|
||||||
) {
|
) {
|
||||||
// initialization
|
val m = block.toULongArray()
|
||||||
val v = ULongArray(16)
|
val v = ULongArray(16)
|
||||||
for (i in 0..<8) v[i] = h[i]
|
for (i in 0..<8) v[i] = h[i]
|
||||||
for (i in 0..<4) v[i + 8] = c[i]
|
for (i in 0..<4) v[i + 8] = c[i]
|
||||||
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
|
for (i in 0..<2) v[i + 12] = c[i + 4] xor t
|
||||||
for (i in 0..<2) v[i + 14] = c[i + 6]
|
for (i in 0..<2) v[i + 14] = c[i + 6]
|
||||||
|
|
||||||
// rounds
|
repeat(16) { r ->
|
||||||
for (r in 0..<16) {
|
|
||||||
val s = sigma[r % 10]
|
val s = sigma[r % 10]
|
||||||
|
|
||||||
// column
|
|
||||||
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
|
g(v, 0, 4, 8, 12, m[s[0]] xor c[s[1]], m[s[1]] xor c[s[0]])
|
||||||
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
|
g(v, 1, 5, 9, 13, m[s[2]] xor c[s[3]], m[s[3]] xor c[s[2]])
|
||||||
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
|
g(v, 2, 6, 10, 14, m[s[4]] xor c[s[5]], m[s[5]] xor c[s[4]])
|
||||||
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
|
g(v, 3, 7, 11, 15, m[s[6]] xor c[s[7]], m[s[7]] xor c[s[6]])
|
||||||
|
|
||||||
// diagonal
|
|
||||||
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
|
g(v, 0, 5, 10, 15, m[s[8]] xor c[s[9]], m[s[9]] xor c[s[8]])
|
||||||
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
|
g(v, 1, 6, 11, 12, m[s[10]] xor c[s[11]], m[s[11]] xor c[s[10]])
|
||||||
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
|
g(v, 2, 7, 8, 13, m[s[12]] xor c[s[13]], m[s[13]] xor c[s[12]])
|
||||||
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
|
g(v, 3, 4, 9, 14, m[s[14]] xor c[s[15]], m[s[15]] xor c[s[14]])
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalization
|
|
||||||
for (i in 0..7) {
|
for (i in 0..7) {
|
||||||
h[i] = h[i] xor v[i] xor v[i + 8]
|
h[i] = h[i] xor v[i] xor v[i + 8]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// round function
|
|
||||||
private fun g(
|
private fun g(
|
||||||
v: ULongArray,
|
v: ULongArray,
|
||||||
a: Int,
|
a: Int,
|
||||||
|
|||||||
@@ -36,65 +36,60 @@ class Blake2b(
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun hash(value: UByteArray): UByteArray {
|
override fun hash(value: UByteArray): UByteArray {
|
||||||
|
val l = value.size.toULong()
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
h[0] = h[0] xor (0x01010000UL or bytes.toULong())
|
h[0] = h[0] xor (0x01010000UL or bytes.toULong())
|
||||||
var t = 0UL
|
var t = 0UL
|
||||||
val l = value.size.toULong()
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(128) { it.toUByteArray() }
|
||||||
|
for ((i, block) in blocks.withIndex()) {
|
||||||
|
t += minOf(l - t, 128UL)
|
||||||
|
compress(h, block, t, i == blocks.lastIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.toUByteArray(ByteOrder.LITTLE_ENDIAN).sliceArray(0..<bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
if (isEmpty()) add(0x00U)
|
if (isEmpty()) add(0x00U)
|
||||||
while (size % 128 != 0) {
|
while (size % 128 != 0) {
|
||||||
add(0x00U)
|
add(0x00U)
|
||||||
}
|
}
|
||||||
}.toUByteArray()
|
}.toUByteArray()
|
||||||
|
|
||||||
// compress
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(128) { it.toUByteArray() }
|
|
||||||
for ((i, block) in blocks.withIndex()) {
|
|
||||||
t += minOf(l - t, 128UL)
|
|
||||||
|
|
||||||
val m = block.toULongArray()
|
|
||||||
compress(h, m, t, i == blocks.lastIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.toUByteArray(ByteOrder.LITTLE_ENDIAN).sliceArray(0..<bytes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compress(
|
private fun compress(
|
||||||
h: ULongArray,
|
h: ULongArray,
|
||||||
m: ULongArray,
|
block: UByteArray,
|
||||||
t: ULong,
|
t: ULong,
|
||||||
last: Boolean,
|
last: Boolean,
|
||||||
) {
|
) {
|
||||||
// initialization
|
val m = block.toULongArray()
|
||||||
val v = ULongArray(16)
|
val v = ULongArray(16)
|
||||||
for (i in 0..<8) v[i] = h[i]
|
for (i in 0..<8) v[i] = h[i]
|
||||||
for (i in 0..<8) v[i + 8] = initial[i]
|
for (i in 0..<8) v[i + 8] = initial[i]
|
||||||
|
|
||||||
v[12] = v[12] xor t
|
v[12] = v[12] xor t
|
||||||
if (last) v[14] = v[14].inv()
|
if (last) v[14] = v[14].inv()
|
||||||
|
|
||||||
// rounds
|
repeat(12) { r ->
|
||||||
for (r in 0..<12) {
|
|
||||||
val s = sigma[r % 10]
|
val s = sigma[r % 10]
|
||||||
|
|
||||||
// column
|
|
||||||
mix(v, 0, 4, 8, 12, m[s[0]], m[s[1]])
|
mix(v, 0, 4, 8, 12, m[s[0]], m[s[1]])
|
||||||
mix(v, 1, 5, 9, 13, m[s[2]], m[s[3]])
|
mix(v, 1, 5, 9, 13, m[s[2]], m[s[3]])
|
||||||
mix(v, 2, 6, 10, 14, m[s[4]], m[s[5]])
|
mix(v, 2, 6, 10, 14, m[s[4]], m[s[5]])
|
||||||
mix(v, 3, 7, 11, 15, m[s[6]], m[s[7]])
|
mix(v, 3, 7, 11, 15, m[s[6]], m[s[7]])
|
||||||
|
|
||||||
// diagonal
|
|
||||||
mix(v, 0, 5, 10, 15, m[s[8]], m[s[9]])
|
mix(v, 0, 5, 10, 15, m[s[8]], m[s[9]])
|
||||||
mix(v, 1, 6, 11, 12, m[s[10]], m[s[11]])
|
mix(v, 1, 6, 11, 12, m[s[10]], m[s[11]])
|
||||||
mix(v, 2, 7, 8, 13, m[s[12]], m[s[13]])
|
mix(v, 2, 7, 8, 13, m[s[12]], m[s[13]])
|
||||||
mix(v, 3, 4, 9, 14, m[s[14]], m[s[15]])
|
mix(v, 3, 4, 9, 14, m[s[14]], m[s[15]])
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalization
|
|
||||||
for (i in 0..7) {
|
for (i in 0..7) {
|
||||||
h[i] = h[i] xor v[i] xor v[i + 8]
|
h[i] = h[i] xor v[i] xor v[i + 8]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,40 +36,40 @@ class Blake2s(
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun hash(value: UByteArray): UByteArray {
|
override fun hash(value: UByteArray): UByteArray {
|
||||||
|
val l = value.size.toULong()
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
h[0] = h[0] xor (0x01010000U or bytes.toUInt())
|
h[0] = h[0] xor (0x01010000U or bytes.toUInt())
|
||||||
var t = 0U
|
var t = 0U
|
||||||
val l = value.size.toULong()
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(64) { it.toUByteArray() }
|
||||||
|
for ((i, block) in blocks.withIndex()) {
|
||||||
|
t += minOf(l - t, 64UL).toUInt()
|
||||||
|
compress(h, block, t, i == blocks.lastIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.toUByteArray(LITTLE_ENDIAN).sliceArray(0..<bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
if (isEmpty()) add(0x00U)
|
if (isEmpty()) add(0x00U)
|
||||||
while (size % 64 != 0) {
|
while (size % 64 != 0) {
|
||||||
add(0x00U)
|
add(0x00U)
|
||||||
}
|
}
|
||||||
}.toUByteArray()
|
}.toUByteArray()
|
||||||
|
|
||||||
// compress
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(64) { it.toUByteArray() }
|
|
||||||
for ((i, block) in blocks.withIndex()) {
|
|
||||||
t += minOf(l - t, 64U).toUInt()
|
|
||||||
|
|
||||||
val m = block.toUIntArray()
|
|
||||||
compress(h, m, t, i == blocks.lastIndex)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.toUByteArray(LITTLE_ENDIAN).sliceArray(0..<bytes)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun compress(
|
private fun compress(
|
||||||
h: UIntArray,
|
h: UIntArray,
|
||||||
m: UIntArray,
|
block: UByteArray,
|
||||||
t: UInt,
|
t: UInt,
|
||||||
last: Boolean,
|
last: Boolean,
|
||||||
) {
|
) {
|
||||||
// initialization
|
val m = block.toUIntArray()
|
||||||
val v = UIntArray(16)
|
val v = UIntArray(16)
|
||||||
for (i in 0..<8) v[i] = h[i]
|
for (i in 0..<8) v[i] = h[i]
|
||||||
for (i in 0..<8) v[i + 8] = initial[i]
|
for (i in 0..<8) v[i + 8] = initial[i]
|
||||||
@@ -77,24 +77,20 @@ class Blake2s(
|
|||||||
v[12] = v[12] xor t
|
v[12] = v[12] xor t
|
||||||
if (last) v[14] = v[14].inv()
|
if (last) v[14] = v[14].inv()
|
||||||
|
|
||||||
// rounds
|
repeat(10) { r ->
|
||||||
for (r in 0..<10) {
|
|
||||||
val s = sigma[r]
|
val s = sigma[r]
|
||||||
|
|
||||||
// column
|
|
||||||
mix(v, 0, 4, 8, 12, m[s[0]], m[s[1]])
|
mix(v, 0, 4, 8, 12, m[s[0]], m[s[1]])
|
||||||
mix(v, 1, 5, 9, 13, m[s[2]], m[s[3]])
|
mix(v, 1, 5, 9, 13, m[s[2]], m[s[3]])
|
||||||
mix(v, 2, 6, 10, 14, m[s[4]], m[s[5]])
|
mix(v, 2, 6, 10, 14, m[s[4]], m[s[5]])
|
||||||
mix(v, 3, 7, 11, 15, m[s[6]], m[s[7]])
|
mix(v, 3, 7, 11, 15, m[s[6]], m[s[7]])
|
||||||
|
|
||||||
// diagonal
|
|
||||||
mix(v, 0, 5, 10, 15, m[s[8]], m[s[9]])
|
mix(v, 0, 5, 10, 15, m[s[8]], m[s[9]])
|
||||||
mix(v, 1, 6, 11, 12, m[s[10]], m[s[11]])
|
mix(v, 1, 6, 11, 12, m[s[10]], m[s[11]])
|
||||||
mix(v, 2, 7, 8, 13, m[s[12]], m[s[13]])
|
mix(v, 2, 7, 8, 13, m[s[12]], m[s[13]])
|
||||||
mix(v, 3, 4, 9, 14, m[s[14]], m[s[15]])
|
mix(v, 3, 4, 9, 14, m[s[14]], m[s[15]])
|
||||||
}
|
}
|
||||||
|
|
||||||
// finalization
|
|
||||||
for (i in 0..7) {
|
for (i in 0..7) {
|
||||||
h[i] = h[i] xor v[i] xor v[i + 8]
|
h[i] = h[i] xor v[i] xor v[i + 8]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,44 +41,39 @@ open class Keccak(
|
|||||||
): UByteArray {
|
): UByteArray {
|
||||||
val state = ULongArray(25)
|
val state = ULongArray(25)
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(rate) { it.toUByteArray() }
|
||||||
|
for (block in blocks) {
|
||||||
|
absorb(state, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
return squeeze(state)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
add(domain)
|
add(domain)
|
||||||
while ((size % rate) != (rate - 1)) {
|
while ((size % rate) != (rate - 1)) {
|
||||||
add(0x00U)
|
add(0x00U)
|
||||||
}
|
}
|
||||||
add(0x80U)
|
add(0x80U)
|
||||||
}
|
|
||||||
|
|
||||||
// absorb
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(rate) { it.toUByteArray() }
|
|
||||||
for (block in blocks) {
|
|
||||||
val numbers = block.toULongArray(LITTLE_ENDIAN)
|
|
||||||
for ((i, number) in numbers.withIndex()) {
|
|
||||||
state[i] = state[i] xor number
|
|
||||||
}
|
|
||||||
permute(state)
|
|
||||||
}
|
|
||||||
|
|
||||||
// squeeze
|
|
||||||
return buildList {
|
|
||||||
var i = 0
|
|
||||||
while (size < bytes) {
|
|
||||||
if (i == rate / 8) {
|
|
||||||
permute(state)
|
|
||||||
i = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
addAll(
|
|
||||||
state[i++].toUByteArray(LITTLE_ENDIAN)
|
|
||||||
.sliceArray(0..<min(bytes - size, 8))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}.toUByteArray()
|
}.toUByteArray()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun absorb(
|
||||||
|
state: ULongArray,
|
||||||
|
block: UByteArray,
|
||||||
|
) {
|
||||||
|
val numbers = block.toULongArray(LITTLE_ENDIAN)
|
||||||
|
for ((i, number) in numbers.withIndex()) {
|
||||||
|
state[i] = state[i] xor number
|
||||||
|
}
|
||||||
|
permute(state)
|
||||||
|
}
|
||||||
|
|
||||||
private fun permute(
|
private fun permute(
|
||||||
a: ULongArray,
|
a: ULongArray,
|
||||||
) {
|
) {
|
||||||
@@ -112,4 +107,22 @@ open class Keccak(
|
|||||||
a[0] = a[0] xor rc[round]
|
a[0] = a[0] xor rc[round]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun squeeze(
|
||||||
|
state: ULongArray,
|
||||||
|
): UByteArray {
|
||||||
|
return buildList {
|
||||||
|
var i = 0
|
||||||
|
while (size < bytes) {
|
||||||
|
if (i == rate / 8) {
|
||||||
|
permute(state)
|
||||||
|
i = 0
|
||||||
|
}
|
||||||
|
addAll(
|
||||||
|
state[i++].toUByteArray(LITTLE_ENDIAN)
|
||||||
|
.sliceArray(0..<min(bytes - size, 8))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}.toUByteArray()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,36 +51,38 @@ object MD5 : HashFunction() {
|
|||||||
value: UByteArray,
|
value: UByteArray,
|
||||||
): UByteArray {
|
): UByteArray {
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
val l = value.size.toULong() * 8UL
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(64) { it.toUByteArray() }
|
||||||
|
for (block in blocks) {
|
||||||
|
process(h, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.toUByteArray(LITTLE_ENDIAN)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
add(0x80U)
|
add(0x80U)
|
||||||
while (size % 64 != 56) {
|
while (size % 64 != 56) {
|
||||||
add(0x00U)
|
add(0x00U)
|
||||||
}
|
}
|
||||||
addAll(l.toUByteArray(LITTLE_ENDIAN))
|
addAll(l.toUByteArray(LITTLE_ENDIAN))
|
||||||
}
|
}.toUByteArray()
|
||||||
|
|
||||||
// process
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(64) { it.toUByteArray() }
|
|
||||||
for (block in blocks) {
|
|
||||||
val w = block.toUIntArray(LITTLE_ENDIAN)
|
|
||||||
process(h, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.toUByteArray(LITTLE_ENDIAN)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun process(
|
private fun process(
|
||||||
h: UIntArray,
|
h: UIntArray,
|
||||||
w: UIntArray,
|
block: UByteArray,
|
||||||
) {
|
) {
|
||||||
|
val w = block.toUIntArray(LITTLE_ENDIAN)
|
||||||
val v = h.copyOf()
|
val v = h.copyOf()
|
||||||
|
|
||||||
for (i in 0..<64) {
|
repeat(64) { i ->
|
||||||
var f = when (i) {
|
var f = when (i) {
|
||||||
in 0..15 -> (v[1] and v[2]) or (v[1].inv() and v[3])
|
in 0..15 -> (v[1] and v[2]) or (v[1].inv() and v[3])
|
||||||
in 16..31 -> (v[3] and v[1]) or (v[3].inv() and v[2])
|
in 16..31 -> (v[3] and v[1]) or (v[3].inv() and v[2])
|
||||||
|
|||||||
@@ -21,42 +21,44 @@ object SHA1 : HashFunction() {
|
|||||||
value: UByteArray,
|
value: UByteArray,
|
||||||
): UByteArray {
|
): UByteArray {
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
val l = value.size.toULong() * 8UL
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(64) { it.toUByteArray() }
|
||||||
|
for (block in blocks) {
|
||||||
|
process(h, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
add(0x80U)
|
add(0x80U)
|
||||||
while (size % 64 != 56) {
|
while (size % 64 != 56) {
|
||||||
add(0x00U)
|
add(0x00U)
|
||||||
}
|
}
|
||||||
addAll(l.toUByteArray())
|
addAll(l.toUByteArray())
|
||||||
}
|
}.toUByteArray()
|
||||||
|
|
||||||
// process
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(64) { it.toUByteArray() }
|
|
||||||
for (block in blocks) {
|
|
||||||
val w = buildList {
|
|
||||||
addAll(block.toUIntArray())
|
|
||||||
for (i in 16..<80) {
|
|
||||||
val word = (get(i - 3) xor get(i - 8) xor get(i - 14) xor get(i - 16)).rotateLeft(1)
|
|
||||||
add(word)
|
|
||||||
}
|
|
||||||
}.toUIntArray()
|
|
||||||
process(h, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.toUByteArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun process(
|
private fun process(
|
||||||
h: UIntArray,
|
h: UIntArray,
|
||||||
w: UIntArray,
|
block: UByteArray,
|
||||||
) {
|
) {
|
||||||
|
val w = buildList {
|
||||||
|
addAll(block.toUIntArray())
|
||||||
|
for (i in 16..79) {
|
||||||
|
val word = (get(i - 3) xor get(i - 8) xor get(i - 14) xor get(i - 16)).rotateLeft(1)
|
||||||
|
add(word)
|
||||||
|
}
|
||||||
|
}.toUIntArray()
|
||||||
val v = h.copyOf()
|
val v = h.copyOf()
|
||||||
|
|
||||||
for (i in 0..<80) {
|
repeat(80) { i ->
|
||||||
val f = when (i) {
|
val f = when (i) {
|
||||||
in 0..<20 -> (v[1] and v[2]) or (v[1].inv() and v[3])
|
in 0..<20 -> (v[1] and v[2]) or (v[1].inv() and v[3])
|
||||||
in 20..<40 -> v[1] xor v[2] xor v[3]
|
in 20..<40 -> v[1] xor v[2] xor v[3]
|
||||||
|
|||||||
@@ -33,43 +33,45 @@ object `SHA-224` : HashFunction() {
|
|||||||
value: UByteArray,
|
value: UByteArray,
|
||||||
): UByteArray {
|
): UByteArray {
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
val l = value.size.toULong() * 8UL
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(64) { it.toUByteArray() }
|
||||||
|
for (block in blocks) {
|
||||||
|
process(h, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.sliceArray(0..6).toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
add(0x80U)
|
add(0x80U)
|
||||||
while (size % 64 != 56) {
|
while (size % 64 != 56) {
|
||||||
add(0x00U)
|
add(0x00U)
|
||||||
}
|
}
|
||||||
addAll(l.toUByteArray())
|
addAll(l.toUByteArray())
|
||||||
}
|
}.toUByteArray()
|
||||||
|
|
||||||
// process
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(64) { it.toUByteArray() }
|
|
||||||
for (block in blocks) {
|
|
||||||
val w = buildList {
|
|
||||||
addAll(block.toUIntArray())
|
|
||||||
for (i in 16..<64) {
|
|
||||||
val s0 = get(i - 15).rotateRight(7) xor get(i - 15).rotateRight(18) xor (get(i - 15) shr 3)
|
|
||||||
val s1 = get(i - 2).rotateRight(17) xor get(i - 2).rotateRight(19) xor (get(i - 2) shr 10)
|
|
||||||
add(get(i - 16) + s0 + get(i - 7) + s1)
|
|
||||||
}
|
|
||||||
}.toUIntArray()
|
|
||||||
process(h, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.sliceArray(0..6).toUByteArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun process(
|
private fun process(
|
||||||
h: UIntArray,
|
h: UIntArray,
|
||||||
w: UIntArray,
|
block: UByteArray,
|
||||||
) {
|
) {
|
||||||
|
val w = buildList {
|
||||||
|
addAll(block.toUIntArray())
|
||||||
|
for (i in 16..63) {
|
||||||
|
val s0 = get(i - 15).rotateRight(7) xor get(i - 15).rotateRight(18) xor (get(i - 15) shr 3)
|
||||||
|
val s1 = get(i - 2).rotateRight(17) xor get(i - 2).rotateRight(19) xor (get(i - 2) shr 10)
|
||||||
|
add(get(i - 16) + s0 + get(i - 7) + s1)
|
||||||
|
}
|
||||||
|
}.toUIntArray()
|
||||||
val v = h.copyOf()
|
val v = h.copyOf()
|
||||||
|
|
||||||
for (i in 0..<64) {
|
repeat(64) { i ->
|
||||||
val s0 = v[0].rotateRight(2) xor v[0].rotateRight(13) xor v[0].rotateRight(22)
|
val s0 = v[0].rotateRight(2) xor v[0].rotateRight(13) xor v[0].rotateRight(22)
|
||||||
val s1 = v[4].rotateRight(6) xor v[4].rotateRight(11) xor v[4].rotateRight(25)
|
val s1 = v[4].rotateRight(6) xor v[4].rotateRight(11) xor v[4].rotateRight(25)
|
||||||
val ch = (v[4] and v[5]) xor (v[4].inv() and v[6])
|
val ch = (v[4] and v[5]) xor (v[4].inv() and v[6])
|
||||||
|
|||||||
@@ -33,43 +33,45 @@ object `SHA-256` : HashFunction() {
|
|||||||
value: UByteArray,
|
value: UByteArray,
|
||||||
): UByteArray {
|
): UByteArray {
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
val l = value.size.toULong() * 8UL
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(64) { it.toUByteArray() }
|
||||||
|
for (block in blocks) {
|
||||||
|
process(h, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
add(0x80U)
|
add(0x80U)
|
||||||
while (size % 64 != 56) {
|
while (size % 64 != 56) {
|
||||||
add(0x00U)
|
add(0x00U)
|
||||||
}
|
}
|
||||||
addAll(l.toUByteArray())
|
addAll(l.toUByteArray())
|
||||||
}
|
}.toUByteArray()
|
||||||
|
|
||||||
// process
|
|
||||||
val chunks = paddedValue
|
|
||||||
.chunked(64) { it.toUByteArray() }
|
|
||||||
for (chunk in chunks) {
|
|
||||||
val w = buildList {
|
|
||||||
addAll(chunk.toUIntArray())
|
|
||||||
for (i in 16..<64) {
|
|
||||||
val s0 = get(i - 15).rotateRight(7) xor get(i - 15).rotateRight(18) xor (get(i - 15) shr 3)
|
|
||||||
val s1 = get(i - 2).rotateRight(17) xor get(i - 2).rotateRight(19) xor (get(i - 2) shr 10)
|
|
||||||
add(get(i - 16) + s0 + get(i - 7) + s1)
|
|
||||||
}
|
|
||||||
}.toUIntArray()
|
|
||||||
process(h, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.toUByteArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun process(
|
private fun process(
|
||||||
h: UIntArray,
|
h: UIntArray,
|
||||||
w: UIntArray,
|
block: UByteArray,
|
||||||
) {
|
) {
|
||||||
|
val w = buildList {
|
||||||
|
addAll(block.toUIntArray())
|
||||||
|
for (i in 16..63) {
|
||||||
|
val s0 = get(i - 15).rotateRight(7) xor get(i - 15).rotateRight(18) xor (get(i - 15) shr 3)
|
||||||
|
val s1 = get(i - 2).rotateRight(17) xor get(i - 2).rotateRight(19) xor (get(i - 2) shr 10)
|
||||||
|
add(get(i - 16) + s0 + get(i - 7) + s1)
|
||||||
|
}
|
||||||
|
}.toUIntArray()
|
||||||
val v = h.copyOf()
|
val v = h.copyOf()
|
||||||
|
|
||||||
for (i in 0..<64) {
|
repeat(64) { i ->
|
||||||
val s0 = v[0].rotateRight(2) xor v[0].rotateRight(13) xor v[0].rotateRight(22)
|
val s0 = v[0].rotateRight(2) xor v[0].rotateRight(13) xor v[0].rotateRight(22)
|
||||||
val s1 = v[4].rotateRight(6) xor v[4].rotateRight(11) xor v[4].rotateRight(25)
|
val s1 = v[4].rotateRight(6) xor v[4].rotateRight(11) xor v[4].rotateRight(25)
|
||||||
val ch = (v[4] and v[5]) xor (v[4].inv() and v[6])
|
val ch = (v[4] and v[5]) xor (v[4].inv() and v[6])
|
||||||
|
|||||||
@@ -45,43 +45,45 @@ object `SHA-384` : HashFunction() {
|
|||||||
value: UByteArray,
|
value: UByteArray,
|
||||||
): UByteArray {
|
): UByteArray {
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
val l = value.size.toULong() * 8UL
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(128) { it.toUByteArray() }
|
||||||
|
for (block in blocks) {
|
||||||
|
process(h, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.sliceArray(0..5).toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
add(0x80U)
|
add(0x80U)
|
||||||
while (size % 128 != 120) {
|
while (size % 128 != 120) {
|
||||||
add(0x00U)
|
add(0x00U)
|
||||||
}
|
}
|
||||||
addAll(l.toUByteArray())
|
addAll(l.toUByteArray())
|
||||||
}
|
}.toUByteArray()
|
||||||
|
|
||||||
// process
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(128) { it.toUByteArray() }
|
|
||||||
for (block in blocks) {
|
|
||||||
val w = buildList {
|
|
||||||
addAll(block.toULongArray())
|
|
||||||
for (i in 16..<80) {
|
|
||||||
val s0 = get(i - 15).rotateRight(1) xor get(i - 15).rotateRight(8) xor (get(i - 15) shr 7)
|
|
||||||
val s1 = get(i - 2).rotateRight(19) xor get(i - 2).rotateRight(61) xor (get(i - 2) shr 6)
|
|
||||||
add(get(i - 16) + s0 + get(i - 7) + s1)
|
|
||||||
}
|
|
||||||
}.toULongArray()
|
|
||||||
process(h, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.sliceArray(0..5).toUByteArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun process(
|
private fun process(
|
||||||
h: ULongArray,
|
h: ULongArray,
|
||||||
w: ULongArray,
|
block: UByteArray,
|
||||||
) {
|
) {
|
||||||
|
val w = buildList {
|
||||||
|
addAll(block.toULongArray())
|
||||||
|
for (i in 16..79) {
|
||||||
|
val s0 = get(i - 15).rotateRight(1) xor get(i - 15).rotateRight(8) xor (get(i - 15) shr 7)
|
||||||
|
val s1 = get(i - 2).rotateRight(19) xor get(i - 2).rotateRight(61) xor (get(i - 2) shr 6)
|
||||||
|
add(get(i - 16) + s0 + get(i - 7) + s1)
|
||||||
|
}
|
||||||
|
}.toULongArray()
|
||||||
val v = h.copyOf()
|
val v = h.copyOf()
|
||||||
|
|
||||||
for (i in 0..<80) {
|
repeat(80) { i ->
|
||||||
val s0 = v[0].rotateRight(28) xor v[0].rotateRight(34) xor v[0].rotateRight(39)
|
val s0 = v[0].rotateRight(28) xor v[0].rotateRight(34) xor v[0].rotateRight(39)
|
||||||
val s1 = v[4].rotateRight(14) xor v[4].rotateRight(18) xor v[4].rotateRight(41)
|
val s1 = v[4].rotateRight(14) xor v[4].rotateRight(18) xor v[4].rotateRight(41)
|
||||||
val ch = (v[4] and v[5]) xor (v[4].inv() and v[6])
|
val ch = (v[4] and v[5]) xor (v[4].inv() and v[6])
|
||||||
|
|||||||
@@ -45,43 +45,45 @@ object `SHA-512` : HashFunction() {
|
|||||||
value: UByteArray,
|
value: UByteArray,
|
||||||
): UByteArray {
|
): UByteArray {
|
||||||
val h = initial.copyOf()
|
val h = initial.copyOf()
|
||||||
val l = value.size.toULong() * 8UL
|
|
||||||
|
|
||||||
// padding
|
val blocks = pad(value)
|
||||||
val paddedValue = buildList {
|
.chunked(128) { it.toUByteArray() }
|
||||||
|
for (block in blocks) {
|
||||||
|
process(h, block)
|
||||||
|
}
|
||||||
|
|
||||||
|
return h.toUByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun pad(
|
||||||
|
value: UByteArray,
|
||||||
|
): UByteArray {
|
||||||
|
val l = value.size.toULong() * 8UL
|
||||||
|
return buildList {
|
||||||
addAll(value)
|
addAll(value)
|
||||||
add(0x80U)
|
add(0x80U)
|
||||||
while (size % 128 != 120) {
|
while (size % 128 != 120) {
|
||||||
add(0x00U)
|
add(0x00U)
|
||||||
}
|
}
|
||||||
addAll(l.toUByteArray())
|
addAll(l.toUByteArray())
|
||||||
}
|
}.toUByteArray()
|
||||||
|
|
||||||
// process
|
|
||||||
val blocks = paddedValue
|
|
||||||
.chunked(128) { it.toUByteArray() }
|
|
||||||
for (block in blocks) {
|
|
||||||
val w = buildList {
|
|
||||||
addAll(block.toULongArray())
|
|
||||||
for (i in 16..<80) {
|
|
||||||
val s0 = get(i - 15).rotateRight(1) xor get(i - 15).rotateRight(8) xor (get(i - 15) shr 7)
|
|
||||||
val s1 = get(i - 2).rotateRight(19) xor get(i - 2).rotateRight(61) xor (get(i - 2) shr 6)
|
|
||||||
add(get(i - 16) + s0 + get(i - 7) + s1)
|
|
||||||
}
|
|
||||||
}.toULongArray()
|
|
||||||
process(h, w)
|
|
||||||
}
|
|
||||||
|
|
||||||
return h.toUByteArray()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun process(
|
private fun process(
|
||||||
h: ULongArray,
|
h: ULongArray,
|
||||||
w: ULongArray,
|
block: UByteArray,
|
||||||
) {
|
) {
|
||||||
|
val w = buildList {
|
||||||
|
addAll(block.toULongArray())
|
||||||
|
for (i in 16..79) {
|
||||||
|
val s0 = get(i - 15).rotateRight(1) xor get(i - 15).rotateRight(8) xor (get(i - 15) shr 7)
|
||||||
|
val s1 = get(i - 2).rotateRight(19) xor get(i - 2).rotateRight(61) xor (get(i - 2) shr 6)
|
||||||
|
add(get(i - 16) + s0 + get(i - 7) + s1)
|
||||||
|
}
|
||||||
|
}.toULongArray()
|
||||||
val v = h.copyOf()
|
val v = h.copyOf()
|
||||||
|
|
||||||
for (i in 0..<80) {
|
repeat(80) { i ->
|
||||||
val s0 = v[0].rotateRight(28) xor v[0].rotateRight(34) xor v[0].rotateRight(39)
|
val s0 = v[0].rotateRight(28) xor v[0].rotateRight(34) xor v[0].rotateRight(39)
|
||||||
val s1 = v[4].rotateRight(14) xor v[4].rotateRight(18) xor v[4].rotateRight(41)
|
val s1 = v[4].rotateRight(14) xor v[4].rotateRight(18) xor v[4].rotateRight(41)
|
||||||
val ch = (v[4] and v[5]) xor (v[4].inv() and v[6])
|
val ch = (v[4] and v[5]) xor (v[4].inv() and v[6])
|
||||||
|
|||||||
Reference in New Issue
Block a user