WIP implementation of keccak with bellman
This commit is contained in:
parent
86146ddad7
commit
38767db686
24
readable_keccak/Makefile
Normal file
24
readable_keccak/Makefile
Normal file
@ -0,0 +1,24 @@
|
||||
# Makefile
|
||||
# 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
|
||||
BINARY = kctest
|
||||
OBJS = keccak.o main.o
|
||||
DIST = readable_keccak
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -O
|
||||
LIBS =
|
||||
LDFLAGS =
|
||||
INCLUDES =
|
||||
|
||||
$(BINARY): $(OBJS)
|
||||
$(CC) $(LDFLAGS) -o $(BINARY) $(OBJS) $(LIBS)
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -rf $(DIST).tgz $(OBJS) $(BINARY) *~
|
||||
|
||||
dist: clean
|
||||
cd ..; tar cfvz $(DIST)/$(DIST).tgz $(DIST)/*
|
109
readable_keccak/keccak.c
Normal file
109
readable_keccak/keccak.c
Normal file
@ -0,0 +1,109 @@
|
||||
// keccak.c
|
||||
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
// A baseline Keccak (3rd round) implementation.
|
||||
|
||||
#include "keccak.h"
|
||||
|
||||
const uint64_t keccakf_rndc[24] =
|
||||
{
|
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
|
||||
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
|
||||
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
|
||||
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
|
||||
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
|
||||
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
|
||||
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
|
||||
0x8000000000008080, 0x0000000080000001, 0x8000000080008008
|
||||
};
|
||||
|
||||
const int keccakf_rotc[24] =
|
||||
{
|
||||
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
|
||||
27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
|
||||
};
|
||||
|
||||
const int keccakf_piln[24] =
|
||||
{
|
||||
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
|
||||
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
|
||||
};
|
||||
|
||||
// update the state with given number of rounds
|
||||
|
||||
void keccakf(uint64_t st[25], int rounds)
|
||||
{
|
||||
int i, j, round;
|
||||
uint64_t t, bc[5];
|
||||
|
||||
for (round = 0; round < rounds; round++) {
|
||||
|
||||
// Theta
|
||||
for (i = 0; i < 5; i++)
|
||||
bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);
|
||||
for (j = 0; j < 25; j += 5)
|
||||
st[j + i] ^= t;
|
||||
}
|
||||
|
||||
// Rho Pi
|
||||
t = st[1];
|
||||
for (i = 0; i < 24; i++) {
|
||||
j = keccakf_piln[i];
|
||||
bc[0] = st[j];
|
||||
st[j] = ROTL64(t, keccakf_rotc[i]);
|
||||
t = bc[0];
|
||||
}
|
||||
|
||||
// Chi
|
||||
for (j = 0; j < 25; j += 5) {
|
||||
for (i = 0; i < 5; i++)
|
||||
bc[i] = st[j + i];
|
||||
for (i = 0; i < 5; i++)
|
||||
st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
|
||||
}
|
||||
|
||||
// Iota
|
||||
st[0] ^= keccakf_rndc[round];
|
||||
}
|
||||
}
|
||||
|
||||
// compute a keccak hash (md) of given byte length from "in"
|
||||
|
||||
int keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen)
|
||||
{
|
||||
uint64_t st[25];
|
||||
//uint8_t temp[144];
|
||||
int i, rsiz, rsizw;
|
||||
|
||||
rsiz = 200 - 2 * mdlen;
|
||||
rsizw = rsiz / 8;
|
||||
|
||||
memset(st, 0, sizeof(st));
|
||||
|
||||
/*
|
||||
for ( ; inlen >= rsiz; inlen -= rsiz, in += rsiz) {
|
||||
for (i = 0; i < rsizw; i++)
|
||||
st[i] ^= ((uint64_t *) in)[i];
|
||||
keccakf(st, KECCAK_ROUNDS);
|
||||
}
|
||||
|
||||
// last block and padding
|
||||
memcpy(temp, in, inlen);
|
||||
temp[inlen++] = 1;
|
||||
memset(temp + inlen, 0, rsiz - inlen);
|
||||
temp[rsiz - 1] |= 0x80;
|
||||
*/
|
||||
|
||||
for (i = 0; i < rsizw; i++) {
|
||||
st[i] ^= ((uint64_t *) in)[i];
|
||||
}
|
||||
|
||||
keccakf(st, KECCAK_ROUNDS);
|
||||
|
||||
memcpy(md, st, mdlen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
25
readable_keccak/keccak.h
Normal file
25
readable_keccak/keccak.h
Normal file
@ -0,0 +1,25 @@
|
||||
// keccak.h
|
||||
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
|
||||
#ifndef KECCAK_H
|
||||
#define KECCAK_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef KECCAK_ROUNDS
|
||||
#define KECCAK_ROUNDS 24
|
||||
#endif
|
||||
|
||||
#ifndef ROTL64
|
||||
#define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y))))
|
||||
#endif
|
||||
|
||||
// compute a keccak hash (md) of given byte length from "in"
|
||||
int keccak(const uint8_t *in, int inlen, uint8_t *md, int mdlen);
|
||||
|
||||
// update the state
|
||||
void keccakf(uint64_t st[25], int norounds);
|
||||
|
||||
#endif
|
||||
|
162
readable_keccak/main.c
Normal file
162
readable_keccak/main.c
Normal file
@ -0,0 +1,162 @@
|
||||
// main.c
|
||||
// 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "keccak.h"
|
||||
|
||||
// test each length
|
||||
|
||||
typedef struct {
|
||||
int mdlen;
|
||||
char *msgstr;
|
||||
uint8_t md[64];
|
||||
} test_triplet_t;
|
||||
|
||||
// returns zero on success, nonzero + stderr messages on failure
|
||||
|
||||
int keccak_test()
|
||||
{
|
||||
test_triplet_t testvec[4] = {
|
||||
{
|
||||
28, "Keccak-224 Test Hash", {
|
||||
0x30, 0x04, 0x5B, 0x34, 0x94, 0x6E, 0x1B, 0x2E,
|
||||
0x09, 0x16, 0x13, 0x36, 0x2F, 0xD2, 0x2A, 0xA0,
|
||||
0x8E, 0x2B, 0xEA, 0xFE, 0xC5, 0xE8, 0xDA, 0xEE,
|
||||
0x42, 0xC2, 0xE6, 0x65 }
|
||||
}, {
|
||||
32, "Keccak-256 Test Hash", {
|
||||
0xA8, 0xD7, 0x1B, 0x07, 0xF4, 0xAF, 0x26, 0xA4,
|
||||
0xFF, 0x21, 0x02, 0x7F, 0x62, 0xFF, 0x60, 0x26,
|
||||
0x7F, 0xF9, 0x55, 0xC9, 0x63, 0xF0, 0x42, 0xC4,
|
||||
0x6D, 0xA5, 0x2E, 0xE3, 0xCF, 0xAF, 0x3D, 0x3C }
|
||||
}, {
|
||||
48, "Keccak-384 Test Hash", {
|
||||
0xE2, 0x13, 0xFD, 0x74, 0xAF, 0x0C, 0x5F, 0xF9,
|
||||
0x1B, 0x42, 0x3C, 0x8B, 0xCE, 0xEC, 0xD7, 0x01,
|
||||
0xF8, 0xDD, 0x64, 0xEC, 0x18, 0xFD, 0x6F, 0x92,
|
||||
0x60, 0xFC, 0x9E, 0xC1, 0xED, 0xBD, 0x22, 0x30,
|
||||
0xA6, 0x90, 0x86, 0x65, 0xBC, 0xD9, 0xFB, 0xF4,
|
||||
0x1A, 0x99, 0xA1, 0x8A, 0x7D, 0x9E, 0x44, 0x6E }
|
||||
}, {
|
||||
64, "Keccak-512 Test Hash", {
|
||||
0x96, 0xEE, 0x47, 0x18, 0xDC, 0xBA, 0x3C, 0x74,
|
||||
0x61, 0x9B, 0xA1, 0xFA, 0x7F, 0x57, 0xDF, 0xE7,
|
||||
0x76, 0x9D, 0x3F, 0x66, 0x98, 0xA8, 0xB3, 0x3F,
|
||||
0xA1, 0x01, 0x83, 0x89, 0x70, 0xA1, 0x31, 0xE6,
|
||||
0x21, 0xCC, 0xFD, 0x05, 0xFE, 0xFF, 0xBC, 0x11,
|
||||
0x80, 0xF2, 0x63, 0xC2, 0x7F, 0x1A, 0xDA, 0xB4,
|
||||
0x60, 0x95, 0xD6, 0xF1, 0x25, 0x33, 0x14, 0x72,
|
||||
0x4B, 0x5C, 0xBF, 0x78, 0x28, 0x65, 0x8E, 0x6A }
|
||||
}
|
||||
};
|
||||
int i, fails;
|
||||
uint8_t md[64];
|
||||
|
||||
fails = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
|
||||
keccak((uint8_t *) testvec[i].msgstr,
|
||||
strlen(testvec[i].msgstr),
|
||||
md, testvec[i].mdlen);
|
||||
|
||||
if (memcmp(md, testvec[i].md, testvec[i].mdlen)) {
|
||||
fails++;
|
||||
fprintf(stderr, "Keccak-%d FAILED.", testvec[i].mdlen * 8);
|
||||
}
|
||||
}
|
||||
|
||||
return fails;
|
||||
}
|
||||
|
||||
// main
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/*
|
||||
if (keccak_test() == 0)
|
||||
printf("Keccak self-test OK!\n");
|
||||
|
||||
return 0;
|
||||
*/
|
||||
|
||||
uint8_t in[144] = {
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B, 0xFF,
|
||||
0xBB, 0x3B, 0x1B, 0x0B
|
||||
};
|
||||
|
||||
uint8_t md[32] = {0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
keccak(in, 144, md, 32);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
printf("%02x ", md[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
uint64_t st[25] = {
|
||||
0xabcdef0123456789,
|
||||
0x9abcdef012345678,
|
||||
0x89abcdef01234567,
|
||||
0x789abcdef0123456,
|
||||
0x6789abcdef012345,
|
||||
0x56789abcdef01234,
|
||||
0x456789abcdef0123,
|
||||
0x3456789abcdef012,
|
||||
0x23456789abcdef01,
|
||||
0x123456789abcdef0,
|
||||
0x0123456789abcdef,
|
||||
0xf0123456789abcde,
|
||||
0xef0123456789abcd,
|
||||
0xdef0123456789abc,
|
||||
0xcdef0123456789ab,
|
||||
0xbcdef0123456789a,
|
||||
0xabcdef0123456789,
|
||||
0x9abcdef012345678,
|
||||
0x89abcdef01234567,
|
||||
0x789abcdef0123456,
|
||||
0x6789abcdef012345,
|
||||
0x56789abcdef01234,
|
||||
0x456789abcdef0123,
|
||||
0x3456789abcdef012,
|
||||
0x23456789abcdef01
|
||||
};
|
||||
|
||||
keccakf(st, 24);
|
||||
|
||||
if(st[24] == 0x3300e5d2414b6a93) {
|
||||
printf("wow good job\n");
|
||||
}
|
||||
*/
|
||||
}
|
472
src/keccak.rs
Normal file
472
src/keccak.rs
Normal file
@ -0,0 +1,472 @@
|
||||
//use tinysnark::FieldT;
|
||||
|
||||
const keccakf_rndc: [u64; 24] =
|
||||
[
|
||||
0x0000000000000001, 0x0000000000008082, 0x800000000000808a,
|
||||
0x8000000080008000, 0x000000000000808b, 0x0000000080000001,
|
||||
0x8000000080008081, 0x8000000000008009, 0x000000000000008a,
|
||||
0x0000000000000088, 0x0000000080008009, 0x000000008000000a,
|
||||
0x000000008000808b, 0x800000000000008b, 0x8000000000008089,
|
||||
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,
|
||||
0x000000000000800a, 0x800000008000000a, 0x8000000080008081,
|
||||
0x8000000000008080, 0x0000000080000001, 0x8000000080008008
|
||||
];
|
||||
|
||||
const keccakf_rotc: [usize; 24] =
|
||||
[
|
||||
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14,
|
||||
27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
|
||||
];
|
||||
|
||||
const keccakf_piln: [usize; 24] =
|
||||
[
|
||||
10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4,
|
||||
15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
|
||||
];
|
||||
|
||||
fn keccakf(st: &mut [Chunk; 25], rounds: usize)
|
||||
{
|
||||
for round in 0..rounds {
|
||||
/*
|
||||
// Theta
|
||||
for (i = 0; i < 5; i++)
|
||||
bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20];
|
||||
*/
|
||||
|
||||
// TODO: Rust arrays don't implement FromIterator.
|
||||
let mut bc: [Option<Chunk>; 5] = [None, None, None, None, None];
|
||||
|
||||
for i in 0..5 {
|
||||
bc[i] = Some(st[i]
|
||||
.xor(&st[i+5])
|
||||
.xor(&st[i+10])
|
||||
.xor(&st[i+15])
|
||||
.xor(&st[i+20]));
|
||||
}
|
||||
|
||||
let mut bc: [Chunk; 5] = [bc[0].take().unwrap(),
|
||||
bc[1].take().unwrap(),
|
||||
bc[2].take().unwrap(),
|
||||
bc[3].take().unwrap(),
|
||||
bc[4].take().unwrap()];
|
||||
|
||||
/*
|
||||
for (i = 0; i < 5; i++) {
|
||||
t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1);
|
||||
for (j = 0; j < 25; j += 5)
|
||||
st[j + i] ^= t;
|
||||
}
|
||||
*/
|
||||
|
||||
for i in 0..5 {
|
||||
let tmp = bc[(i + 4) % 5].xor(&bc[(i + 1) % 5].rotl(1));
|
||||
|
||||
for j in (0..25).filter(|a| a % 5 == 0) {
|
||||
st[j + i] = tmp.xor(&st[j + i]);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
// Rho Pi
|
||||
t = st[1];
|
||||
for (i = 0; i < 24; i++) {
|
||||
j = keccakf_piln[i];
|
||||
bc[0] = st[j];
|
||||
st[j] = ROTL64(t, keccakf_rotc[i]);
|
||||
t = bc[0];
|
||||
}
|
||||
*/
|
||||
let mut tmp = st[1].clone();
|
||||
|
||||
for i in 0..24 {
|
||||
let j = keccakf_piln[i];
|
||||
|
||||
bc[0] = st[j].clone();
|
||||
st[j] = tmp.rotl(keccakf_rotc[i]);
|
||||
tmp = bc[0].clone();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
/*
|
||||
// Chi
|
||||
for (j = 0; j < 25; j += 5) {
|
||||
for (i = 0; i < 5; i++)
|
||||
bc[i] = st[j + i];
|
||||
for (i = 0; i < 5; i++)
|
||||
st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5];
|
||||
}
|
||||
*/
|
||||
|
||||
for j in (0..25).filter(|a| a % 5 == 0) {
|
||||
for i in 0..5 {
|
||||
bc[i] = st[j + i].clone();
|
||||
}
|
||||
|
||||
for i in 0..5 {
|
||||
st[j + i] = st[j + i].xor(&bc[(i + 1) % 5].notand(&bc[(i + 2) % 5]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Iota
|
||||
st[0] ^= keccakf_rndc[round];
|
||||
*/
|
||||
|
||||
st[0] = st[0].xor(&keccakf_rndc[round].into());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: don't return a vec. currently don't have any
|
||||
// more patience for rust's awful arrays
|
||||
fn keccak256(mut input: &[[Bit; 8]]) -> Vec<Bit> {
|
||||
assert_eq!(input.len(), 144);
|
||||
|
||||
let mut st: [Chunk; 25] = [Chunk::from(0), Chunk::from(0), Chunk::from(0), Chunk::from(0), Chunk::from(0),
|
||||
Chunk::from(0), Chunk::from(0), Chunk::from(0), Chunk::from(0), Chunk::from(0),
|
||||
Chunk::from(0), Chunk::from(0), Chunk::from(0), Chunk::from(0), Chunk::from(0),
|
||||
Chunk::from(0), Chunk::from(0), Chunk::from(0), Chunk::from(0), Chunk::from(0),
|
||||
Chunk::from(0), Chunk::from(0), Chunk::from(0), Chunk::from(0), Chunk::from(0)
|
||||
];
|
||||
|
||||
let mdlen = 32; // 256 bit
|
||||
let rsiz = 200 - 2 * mdlen;
|
||||
let rsizw = rsiz / 8;
|
||||
|
||||
for i in 0..rsizw {
|
||||
let j = i * 8;
|
||||
st[i] = st[i].xor(&Chunk::from(&input[j..(j+8)]));
|
||||
}
|
||||
|
||||
keccakf(&mut st, 24);
|
||||
|
||||
let mut v = vec![];
|
||||
for i in 0..4 {
|
||||
// due to endianness...
|
||||
let tmp: Vec<_> = st[i].bits.chunks(8).rev().flat_map(|x| x.iter()).map(|x| x.clone()).collect();
|
||||
v.extend_from_slice(&tmp);
|
||||
}
|
||||
|
||||
assert!(v.len() == 256);
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
struct Chunk {
|
||||
bits: [Bit; 64]
|
||||
}
|
||||
|
||||
impl Clone for Chunk {
|
||||
fn clone(&self) -> Chunk {
|
||||
let mut new_chunk = Chunk::from(0);
|
||||
|
||||
for i in 0..64 {
|
||||
new_chunk.bits[i] = self.bits[i].clone();
|
||||
}
|
||||
|
||||
new_chunk
|
||||
}
|
||||
}
|
||||
|
||||
impl Chunk {
|
||||
fn xor(&self, other: &Chunk) -> Chunk {
|
||||
let mut new_chunk = Chunk::from(0);
|
||||
|
||||
for i in 0..64 {
|
||||
new_chunk.bits[i] = self.bits[i].xor(&other.bits[i]);
|
||||
}
|
||||
|
||||
new_chunk
|
||||
}
|
||||
|
||||
fn notand(&self, other: &Chunk) -> Chunk {
|
||||
let mut new_chunk = Chunk::from(0);
|
||||
|
||||
for i in 0..64 {
|
||||
new_chunk.bits[i] = self.bits[i].notand(&other.bits[i]);
|
||||
}
|
||||
|
||||
new_chunk
|
||||
}
|
||||
|
||||
fn rotl(&self, by: usize) -> Chunk {
|
||||
assert!(by < 64);
|
||||
let mut new_bits = vec![];
|
||||
|
||||
new_bits.extend_from_slice(&self.bits[by..]);
|
||||
new_bits.extend_from_slice(&self.bits[0..by]);
|
||||
|
||||
let mut clone = self.clone();
|
||||
clone.bits.clone_from_slice(&new_bits);
|
||||
|
||||
clone
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Chunk {
|
||||
fn eq(&self, other: &Chunk) -> bool {
|
||||
for (a, b) in self.bits.iter().zip(other.bits.iter()) {
|
||||
if a != b { return false; }
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a [[Bit; 8]]> for Chunk {
|
||||
fn from(bytes: &'a [[Bit; 8]]) -> Chunk {
|
||||
assert!(bytes.len() == 8); // must be 64 bit
|
||||
|
||||
let mut new_chunk = Chunk::from(0);
|
||||
|
||||
for (i, byte) in bytes.iter().rev().enumerate() {
|
||||
for (j, bit) in byte.iter().enumerate() {
|
||||
new_chunk.bits[i*8 + j] = bit.clone();
|
||||
}
|
||||
}
|
||||
|
||||
new_chunk
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> From<&'a [Bit]> for Chunk {
|
||||
fn from(bits: &'a [Bit]) -> Chunk {
|
||||
assert!(bits.len() == 64); // must be 64 bit
|
||||
|
||||
let mut new_chunk = Chunk::from(0);
|
||||
|
||||
for (i, bit) in bits.iter().enumerate() {
|
||||
new_chunk.bits[i] = bit.clone();
|
||||
}
|
||||
|
||||
new_chunk
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u64> for Chunk {
|
||||
fn from(num: u64) -> Chunk {
|
||||
use std::mem;
|
||||
|
||||
fn bit_at(num: u64, i: usize) -> u8 {
|
||||
((num << i) >> 63) as u8
|
||||
}
|
||||
|
||||
// TODO: initialize this with unsafe { }
|
||||
// sadly... GET INTEGER GENERICS WORKING RUST
|
||||
Chunk {
|
||||
bits: [
|
||||
Bit::constant(bit_at(num, 0)),
|
||||
Bit::constant(bit_at(num, 1)),
|
||||
Bit::constant(bit_at(num, 2)),
|
||||
Bit::constant(bit_at(num, 3)),
|
||||
Bit::constant(bit_at(num, 4)),
|
||||
Bit::constant(bit_at(num, 5)),
|
||||
Bit::constant(bit_at(num, 6)),
|
||||
Bit::constant(bit_at(num, 7)),
|
||||
Bit::constant(bit_at(num, 8)),
|
||||
Bit::constant(bit_at(num, 9)),
|
||||
Bit::constant(bit_at(num, 10)),
|
||||
Bit::constant(bit_at(num, 11)),
|
||||
Bit::constant(bit_at(num, 12)),
|
||||
Bit::constant(bit_at(num, 13)),
|
||||
Bit::constant(bit_at(num, 14)),
|
||||
Bit::constant(bit_at(num, 15)),
|
||||
Bit::constant(bit_at(num, 16)),
|
||||
Bit::constant(bit_at(num, 17)),
|
||||
Bit::constant(bit_at(num, 18)),
|
||||
Bit::constant(bit_at(num, 19)),
|
||||
Bit::constant(bit_at(num, 20)),
|
||||
Bit::constant(bit_at(num, 21)),
|
||||
Bit::constant(bit_at(num, 22)),
|
||||
Bit::constant(bit_at(num, 23)),
|
||||
Bit::constant(bit_at(num, 24)),
|
||||
Bit::constant(bit_at(num, 25)),
|
||||
Bit::constant(bit_at(num, 26)),
|
||||
Bit::constant(bit_at(num, 27)),
|
||||
Bit::constant(bit_at(num, 28)),
|
||||
Bit::constant(bit_at(num, 29)),
|
||||
Bit::constant(bit_at(num, 30)),
|
||||
Bit::constant(bit_at(num, 31)),
|
||||
Bit::constant(bit_at(num, 32)),
|
||||
Bit::constant(bit_at(num, 33)),
|
||||
Bit::constant(bit_at(num, 34)),
|
||||
Bit::constant(bit_at(num, 35)),
|
||||
Bit::constant(bit_at(num, 36)),
|
||||
Bit::constant(bit_at(num, 37)),
|
||||
Bit::constant(bit_at(num, 38)),
|
||||
Bit::constant(bit_at(num, 39)),
|
||||
Bit::constant(bit_at(num, 40)),
|
||||
Bit::constant(bit_at(num, 41)),
|
||||
Bit::constant(bit_at(num, 42)),
|
||||
Bit::constant(bit_at(num, 43)),
|
||||
Bit::constant(bit_at(num, 44)),
|
||||
Bit::constant(bit_at(num, 45)),
|
||||
Bit::constant(bit_at(num, 46)),
|
||||
Bit::constant(bit_at(num, 47)),
|
||||
Bit::constant(bit_at(num, 48)),
|
||||
Bit::constant(bit_at(num, 49)),
|
||||
Bit::constant(bit_at(num, 50)),
|
||||
Bit::constant(bit_at(num, 51)),
|
||||
Bit::constant(bit_at(num, 52)),
|
||||
Bit::constant(bit_at(num, 53)),
|
||||
Bit::constant(bit_at(num, 54)),
|
||||
Bit::constant(bit_at(num, 55)),
|
||||
Bit::constant(bit_at(num, 56)),
|
||||
Bit::constant(bit_at(num, 57)),
|
||||
Bit::constant(bit_at(num, 58)),
|
||||
Bit::constant(bit_at(num, 59)),
|
||||
Bit::constant(bit_at(num, 60)),
|
||||
Bit::constant(bit_at(num, 61)),
|
||||
Bit::constant(bit_at(num, 62)),
|
||||
Bit::constant(bit_at(num, 63))
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
enum Bit {
|
||||
Constant(u8)
|
||||
}
|
||||
|
||||
impl Bit {
|
||||
fn byte(byte: u8) -> [Bit; 8] {
|
||||
[
|
||||
Bit::constant({if byte & 0b10000000 != 0 { 1 } else { 0 }}),
|
||||
Bit::constant({if byte & 0b01000000 != 0 { 1 } else { 0 }}),
|
||||
Bit::constant({if byte & 0b00100000 != 0 { 1 } else { 0 }}),
|
||||
Bit::constant({if byte & 0b00010000 != 0 { 1 } else { 0 }}),
|
||||
Bit::constant({if byte & 0b00001000 != 0 { 1 } else { 0 }}),
|
||||
Bit::constant({if byte & 0b00000100 != 0 { 1 } else { 0 }}),
|
||||
Bit::constant({if byte & 0b00000010 != 0 { 1 } else { 0 }}),
|
||||
Bit::constant({if byte & 0b00000001 != 0 { 1 } else { 0 }}),
|
||||
]
|
||||
}
|
||||
|
||||
fn constant(num: u8) -> Bit {
|
||||
assert_eq!((1 - num) * num, 0); // haha
|
||||
|
||||
Bit::Constant(num)
|
||||
}
|
||||
|
||||
// self xor other
|
||||
fn xor(&self, other: &Bit) -> Bit {
|
||||
match (self, other) {
|
||||
(&Bit::Constant(a), &Bit::Constant(b)) => {
|
||||
Bit::constant(a ^ b)
|
||||
},
|
||||
//_ => unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
// (not self) and other
|
||||
fn notand(&self, other: &Bit) -> Bit {
|
||||
match (self, other) {
|
||||
(&Bit::Constant(a), &Bit::Constant(b)) => {
|
||||
Bit::constant((a ^ 1) & b)
|
||||
},
|
||||
//_ => unimplemented!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testsha3() {
|
||||
let bb = |x: usize| {
|
||||
match x % 5 {
|
||||
0 => Bit::byte(0xBB),
|
||||
1 => Bit::byte(0x3B),
|
||||
2 => Bit::byte(0x1B),
|
||||
3 => Bit::byte(0x0B),
|
||||
4 => Bit::byte(0xFF),
|
||||
_ => unreachable!()
|
||||
}
|
||||
};
|
||||
|
||||
let msg: Vec<_> = (0..144).map(bb).collect();
|
||||
|
||||
let result = keccak256(&msg);
|
||||
|
||||
let correct_result: [u64; 4] =
|
||||
[0x6746c5f4559bc1dd,
|
||||
0x49d08e1adcf3be12,
|
||||
0x80a2fcca8ce98789,
|
||||
0x659f40a0053e2989
|
||||
];
|
||||
|
||||
for i in 0..4 {
|
||||
let j = i * 64;
|
||||
let ours = Chunk::from(&result[j..(j+64)]);
|
||||
let correct = Chunk::from(correct_result[i]);
|
||||
|
||||
assert!(ours == correct);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn testff() {
|
||||
let mut a: [Chunk; 25] =
|
||||
[
|
||||
Chunk::from(0xABCDEF0123456789),
|
||||
Chunk::from(0x9ABCDEF012345678),
|
||||
Chunk::from(0x89ABCDEF01234567),
|
||||
Chunk::from(0x789ABCDEF0123456),
|
||||
Chunk::from(0x6789ABCDEF012345),
|
||||
Chunk::from(0x56789ABCDEF01234),
|
||||
Chunk::from(0x456789ABCDEF0123),
|
||||
Chunk::from(0x3456789ABCDEF012),
|
||||
Chunk::from(0x23456789ABCDEF01),
|
||||
Chunk::from(0x123456789ABCDEF0),
|
||||
Chunk::from(0x0123456789ABCDEF),
|
||||
Chunk::from(0xF0123456789ABCDE),
|
||||
Chunk::from(0xEF0123456789ABCD),
|
||||
Chunk::from(0xDEF0123456789ABC),
|
||||
Chunk::from(0xCDEF0123456789AB),
|
||||
Chunk::from(0xBCDEF0123456789A),
|
||||
Chunk::from(0xABCDEF0123456789),
|
||||
Chunk::from(0x9ABCDEF012345678),
|
||||
Chunk::from(0x89ABCDEF01234567),
|
||||
Chunk::from(0x789ABCDEF0123456),
|
||||
Chunk::from(0x6789ABCDEF012345),
|
||||
Chunk::from(0x56789ABCDEF01234),
|
||||
Chunk::from(0x456789ABCDEF0123),
|
||||
Chunk::from(0x3456789ABCDEF012),
|
||||
Chunk::from(0x23456789ABCDEF01)
|
||||
];
|
||||
|
||||
keccakf(&mut a, 24);
|
||||
/*
|
||||
ebf3844f878a7d3b
|
||||
4c9a23df85c470ef
|
||||
4c2e69353217ca2b
|
||||
a3ffa213a668ba9d
|
||||
34082fa7dc4c944b
|
||||
b8bd0a4331665932
|
||||
bfcee841052def2d
|
||||
09e2f6993a65ac0b
|
||||
ec78b15ef42a11e6
|
||||
5088c480e6a77eb8
|
||||
9c1ff840c7758823
|
||||
df8f367ad977a6b1
|
||||
517b9c3505b4195a
|
||||
04624d3094c46c2c
|
||||
e71674d1b70748e2
|
||||
6739a678e25ae9f4
|
||||
2e64f74a9528d091
|
||||
9c17a1105709cbfe
|
||||
54678a20a3ac5925
|
||||
0297df877fa4a559
|
||||
f55ec61b328a5cc5
|
||||
56637274c0f2c301
|
||||
33943408ffd9b9c5
|
||||
f4b87c711ed56d77
|
||||
3300e5d2414b6a93
|
||||
*/
|
||||
assert!(a[0] == Chunk::from(0xebf3844f878a7d3b));
|
||||
assert!(a[1] == Chunk::from(0x4c9a23df85c470ef));
|
||||
assert!(a[2] == Chunk::from(0x4c2e69353217ca2b));
|
||||
assert!(a[3] == Chunk::from(0xa3ffa213a668ba9d));
|
||||
assert!(a[24] == Chunk::from(0x3300e5d2414b6a93));
|
||||
}
|
@ -1,11 +1,17 @@
|
||||
#![feature(clone_from_slice)]
|
||||
|
||||
extern crate tinysnark;
|
||||
extern crate rand;
|
||||
|
||||
use tinysnark::{Proof, Keypair, FieldT, LinearTerm, ConstraintSystem};
|
||||
use std::marker::PhantomData;
|
||||
|
||||
mod keccak;
|
||||
|
||||
fn main() {
|
||||
tinysnark::init();
|
||||
|
||||
/*
|
||||
let mut cs = ConstraintSystem::new(2, 1);
|
||||
// xor
|
||||
// (2*b) * c = b+c - a
|
||||
@ -22,4 +28,5 @@ fn main() {
|
||||
let kp = Keypair::new(&cs);
|
||||
let proof = Proof::new(&kp, &prompt, &solution);
|
||||
assert!(proof.verify(&kp, &prompt));
|
||||
*/
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user