diff --git a/mining_test.go b/mining_test.go deleted file mode 100644 index a2502ea..0000000 --- a/mining_test.go +++ /dev/null @@ -1,346 +0,0 @@ -package main - -import ( - "fmt" - "math" - "math/big" - "encoding/hex" - "github.com/obscuren/sha3" - "testing" -) - -//For use in benchmarking -const tree_depth = 5 -const tape_width = 32 //int(math.Pow(2,tree_depth)) < would be nice, but go won't recognize as const -const tape_depth = 500 - -const Report_Zeros = true - -//Number of operations that are drawn from to form the tape and the tree -const num_ops = 7 -//This is the number of times the PoW algorithm is run -const sample_size = 100 - -func Bytes2Hex(d []byte) string { - return hex.EncodeToString(d) -} - -func Hex2Bytes(str string) []byte { - h, _ := hex.DecodeString(str) - return h -} - -func plus(z *big.Int, x *big.Int, y *big.Int) *big.Int { - var lim big.Int - lim.Exp(big.NewInt(2),big.NewInt(256), big.NewInt(0)) - z.Add(x,y) - return z.Mod(z,&lim) - -} - -func times(z *big.Int, x *big.Int, y *big.Int) *big.Int { - var lim, x1, y1, z1 big.Int - lim.Exp(big.NewInt(2),big.NewInt(256), big.NewInt(0)) - x1.Set(x) - y1.Set(y) - z.Mul(x,y) - z.Mod(z,&lim) - z1 = *big.NewInt(0) - if Report_Zeros { - if (z.Cmp(&z1) == 0 && x1.Cmp(&z1) != 0 && y1.Cmp(&z1) != 0) { - fmt.Printf("-------getting zero---------\n") - fmt.Println(Bytes2Hex(x1.Bytes())) - fmt.Println(Bytes2Hex(y1.Bytes())) - fmt.Println(Bytes2Hex(z.Bytes())) - } - } - return z -} - -func mod(z *big.Int, x *big.Int, y *big.Int) *big.Int { - - if (x.Cmp(big.NewInt(0)) == 0 || y.Cmp(big.NewInt(0)) == 0) { - return big.NewInt(0) - } - if x.Cmp(y) == -1 { //if x < y - z.Mod(y,x) - } else if x.Cmp(y) == 1 { //if x > y - z.Mod(x,y) - } - return z -} - -func xor(z *big.Int, x *big.Int, y *big.Int) *big.Int {return z.Xor(x,y)} -func and(z *big.Int, x *big.Int, y *big.Int) *big.Int {return z.And(x,y)} -func or(z *big.Int, x *big.Int, y *big.Int) *big.Int {return z.Or(x,y)} - -func rshift(z *big.Int, x *big.Int, y *big.Int) *big.Int { - var lim big.Int - lim.Exp(big.NewInt(2),big.NewInt(256), big.NewInt(0)) - z.Rsh(x,7) - return z.Mod(z,&lim) -} - - -func GetOp(i int) func(z *big.Int, x *big.Int, y *big.Int) *big.Int{ - switch i { - case 0: - return plus - case 1: - return rshift - case 2: - return mod - case 3: - return xor - case 4: - return and - case 5: - return or - case 6: - return times - } - return plus -} - -type Tapelink struct { - I int64 - J int64 - op func(z *big.Int, x *big.Int, y *big.Int) *big.Int -} - -func Sha3Bin(data []byte) []byte { - d := sha3.NewKeccak256() - d.Write(data) - return d.Sum(nil) -} - -func BenchmarkSha3Bin(b *testing.B){ - for i:= 0; i < b.N; i++ { - Sha3Bin([]byte(string(i))) - } -} - -//generates a tape of operations that is w*d long -func gen_tape(seed int64, w int, d int) []Tapelink { - var X = big.NewInt(0) - var Y = big.NewInt(int64(math.Pow(2,32))) - var M = big.NewInt(0) - var T []Tapelink - for i := 0; i < w*d; i++{ - // add empty link to tape - T = append(T, *new(Tapelink)) - - // generate new entropy as needed - if (int64(X.Cmp(Y)) == -1) {X = X.SetBytes(Sha3Bin([]byte(string(seed + int64(i)))))} - - // Pick random index I - T[i].I = M.Mod(X,big.NewInt(int64(w))).Int64() - M = big.NewInt(int64(w)) - X = X.Div(X,M) - - // Pick random index J - mm := big.NewInt(M.Mod(X,big.NewInt(int64(w-1))).Int64() + int64(1) + T[i].I) - T[i].J = M.Mod(mm, big.NewInt(int64(w))).Int64() - M = big.NewInt(int64(w-1)) - X = X.Div(X,M) - - // Pick random operation - T[i].op = GetOp(int(M.Mod(X, big.NewInt(int64(num_ops))).Int64())) - M = big.NewInt(int64(num_ops)) - X = X.Div(X,M) - } - return T -} - -func BenchmarkGen_tape(b *testing.B){ - var X big.Int - var s int64 - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StopTimer() - X.SetBytes(Sha3Bin([]byte(string(i)))) - s = X.Int64() - b.StartTimer() - gen_tape(s, tape_width, tape_depth) - } - -} - -func gen_inputs(seed int64, w int) []big.Int { - var A []big.Int - X := big.NewInt(0) - for i := 0; i < w; i++ { - var B big.Int - A = append(A,B) - if (i % 256 == 0) { - A[i].Set(X.SetBytes(Sha3Bin([]byte(string(seed + int64(i)))))) - } else { - A[i].Set(X.Lsh(X, 1)) - } - } - return A -} - -func BenchmarkGen_inputs(b *testing.B){ - var X big.Int - var s int64 - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StopTimer() - X.SetBytes(Sha3Bin([]byte(string(i)))) - s = X.Int64() - b.StartTimer() - gen_inputs(s, tape_width) - } -} - -//this changes the inputs as it goes through a tape with d links -func run_tape(tape []Tapelink, inputs []big.Int, d int) { - var X *big.Int - X = big.NewInt(0) - for i := 0; i < d; i++ { - X = tape[i].op(X, &inputs[tape[i].I], &inputs[tape[i].J]) - inputs[tape[i].I].Set(X) - } -} - -func BenchmarkRun_tape(b *testing.B){ - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StopTimer() - T := gen_tape(int64(i), tape_width, tape_depth) - I := gen_inputs(int64(i), tape_width) - b.StartTimer() - run_tape(T,I,tape_width*tape_depth) - } - -} - - -//returns a 2^d - 1 length tape of operations (no I or J's in the Tapelinks) -func gen_tree(seed int64, d int) []Tapelink { - M := big.NewInt(0) // dummy variable - X := big.NewInt(0) // entropy variable - Y := big.NewInt(int64(math.Pow(2,32))) // entropy buffer size - var T []Tapelink // the tree will be stored here - - for i := 0; i < int(math.Pow(2, float64(d))) - 1; i++{ - - T = append(T, *new(Tapelink)) - - //giving it more entropy, if X < 2^32 - if (X.Cmp(Y) == -1) {X = X.SetBytes(Sha3Bin([]byte(string(seed + int64(i)))))} - - //filling the tape with random ops - T[i].op = GetOp(int(M.Mod(X, big.NewInt(num_ops)).Int64())) - M = big.NewInt(num_ops) - X = X.Div(X,M) - } - return T -} - -func BenchmarkGen_tree(b *testing.B) { - var X big.Int - var s int64 - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StopTimer() - X.SetBytes(Sha3Bin([]byte(string(i)))) - s = X.Int64() - b.StartTimer() - gen_tree(s, tree_depth) - } -} - -//there should be 2^d inputs and 2^d - 1 links in the tape. not complying is an unhandled exception -func run_tree(inputs []big.Int, tree []Tapelink, d int) *big.Int { - X := big.NewInt(0) - counter := 0 - for j := 0; j < d; j++ { - for i := 0; i < int(math.Pow(2,float64(d - j - 1))); i++ { - X = tree[counter].op(X, &inputs[2*i], &inputs[2*i + 1]) - inputs[i].Set(X) - counter += 1 - } - } - - return &inputs[0] -} - -func BenchmarkRun_tree(b *testing.B) { - var X big.Int - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StopTimer() - var inputs []big.Int - for j := 0; j < tape_width; j++ { - X.SetBytes(Sha3Bin([]byte(string(j + i*tape_width)))) - inputs = append(inputs, X) - } - tree := gen_tree(X.Int64(), tree_depth) - b.StartTimer() - run_tree(inputs, tree, tree_depth) - } -} - -func sha_cap(s []string, n int) []byte{ - var feed string - feed = "" - for i := 0; i < n; i++ { - feed += s[i] - } - return Sha3Bin([]byte(feed)) -} - - -//benchmarked with only one string in the slice, s -func BenchmarkSha_cap(b *testing.B){ - var X big.Int - var s []string - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StopTimer() - X.SetBytes(Sha3Bin([]byte(string(i)))) - s = append(s, X.String()) - b.StartTimer() - sha_cap(s,1) - } -} - - - -func main(){ - var seed int64 - - var sample []big.Int - for i := 0; i < sample_size; i++ { - - if i%5 == 0 { - fmt.Printf("i: %d\n",i) - } - - seed = int64(i) - T := gen_tape(seed, tape_width, tape_depth) - I := gen_inputs(seed, tape_width) - run_tape(T,I, tape_depth*tape_width) - T = gen_tree(seed, tree_depth) - var output big.Int = *run_tree(I,T,tree_depth) - var blockhashes []string - blockhashes = append(blockhashes, output.String()) - H := sha_cap(blockhashes,1) - - output.SetBytes(H) - sample = append(sample, output) - } - - var collisions int = 0 - for i := 0; i < sample_size; i++ { - for j:=0; j < i; j++ { - if(sample[i].Cmp(&sample[j]) == 0) { - collisions += 1 - } - } - } - fmt.Printf("Collisions: %d out of %d\n", (1+int(math.Pow(float64(1+8*collisions),0.5)))/2 - 1, sample_size) -} -