diff options
author | Özgür Kesim <oec@codeblau.de> | 2024-11-21 17:13:47 +0100 |
---|---|---|
committer | Özgür Kesim <oec@codeblau.de> | 2024-11-21 17:13:47 +0100 |
commit | 0ada8c47427bfe604024d383ed7a250b04c82fee (patch) | |
tree | 4bc5e6432512a8060308413d303b675b0658bd1b /stage2_test.go | |
parent | 32cee46e39527a09504615b822cc61969c46184d (diff) |
Diffstat (limited to 'stage2_test.go')
-rw-r--r-- | stage2_test.go | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/stage2_test.go b/stage2_test.go new file mode 100644 index 0000000..e9db755 --- /dev/null +++ b/stage2_test.go @@ -0,0 +1,267 @@ +package seal + +import ( + "slices" + "testing" + + . "kesim.org/seal/common" +) + +func TestStage2Simple1(t *testing.T) { + id := Curve.RandomScalar() + + for _, lost := range []bool{true, false} { + b1 := NewBit(id, !lost) + c1 := b1.StageCommit() + r1, _ := b1.RevealStage1(c1.X) + + // Because the first index is a junction, any subsequent + // combination of Bits must verify with 'lost' set to true + // in the RevealStage2 calls. + for _, s := range [][2]bool{ + {false, false}, + {true, false}, + {false, true}, + {true, true}, + } { + b2 := NewBit(id, s[0]) + b3 := NewBit(id, s[1]) + b4 := NewBit(id, s[1]) // same as b3 + + c2 := b2.StageCommit() + c3 := b3.StageCommit() + c4 := b4.StageCommit() + + r2, p2 := b2.RevealStage2(lost, b1, c1.X, c2.X, c3.X) + if !b2.Commitment.VerifyStage2(c1, c2, r1, r2, p2) { + t.Fatalf("failed to verify b2: %t b3: %t bc2/b1", s[0], s[1]) + } + + r3, p3 := b3.RevealStage2(lost, b1, c1.X, c2.X, c3.X) + if !b3.Commitment.VerifyStage2(c1, c3, r1, r3, p3) { + t.Fatalf("failed to verify b1: %t b3: %t bc3/b1", s[0], s[1]) + } + + r4, p4 := b4.RevealStage2(lost, b1, c1.X, c2.X, c3.X, c4.X) + if !b4.Commitment.VerifyStage2(c1, c4, r1, r4, p4) { + t.Fatalf("failed to verify b1: %t b4: %t bc4/b1", s[0], s[1]) + } + } + } +} + +func int2bits(bid int, bitlength int) []*Bit { + id := Curve.RandomScalar() + + bits := make([]*Bit, bitlength) + for i := range bitlength { + bits[i] = NewBit(id, (bid>>bitlength-i)&1 != 0) + } + return bits +} + +func TestStage2Complex(t *testing.T) { + bid1 := 0b0101 + bid2 := 0b0010 + t.Logf("testing bid1: %05b vs. bid2: %05b", bid1, bid2) + + bitlength := 4 + + bits1 := int2bits(bid1, bitlength) + bits2 := int2bits(bid2, bitlength) + + lost1 := false + lost2 := false + + if len(bits1) != len(bits2) || len(bits1) != bitlength { + t.Fatalf("oops") + } + + instage1 := true + junction := -1 + result := 0 + + for c := 0; c < len(bits1); c++ { + b1 := bits1[c] + b2 := bits2[c] + + c1 := b1.StageCommit() + c2 := b2.StageCommit() + + if instage1 { + t.Logf("Testing bit b1[%d] = %t vs b2[%d] = %t", c, b1.IsSet(), c, b2.IsSet()) + + r1, p1 := b1.RevealStage1(c1.X, c2.X) + r2, p2 := b2.RevealStage1(c1.X, c2.X) + + if !b1.Commitment.VerifyStage1(c1, r1, p1) { + t.Fatalf("b1 commitment failed to verify in stage1") + } + if !b2.Commitment.VerifyStage1(c2, r2, p2) { + t.Fatalf("b2 commitment failed to verify in stage1") + } + + Z := Curve.Product(r1.Z, r2.Z) + if !Id.Equal(Z) { + t.Logf("Aha! Z[%d] != Id, switch to stage2", c) + junction = c + instage1 = false + + if !lost1 && !b1.IsSet() { + t.Logf("setting lost1 to true") + lost1 = true + } + + if !lost2 && !b2.IsSet() { + t.Logf("setting lost2 to true") + lost2 = true + } + result |= 1 << (bitlength - 1 - c) + } else { + t.Logf("Z[%d] == Id, staying in stage1", c) + } + } else { + t.Logf("Testing bit b1[%d]∧lost1 = %t vs b2[%d]∧lost2 = %t", c, b1.IsSet() && !lost1, c, b2.IsSet() && !lost2) + + bj1 := bits1[junction] + bj2 := bits2[junction] + + r1, p1 := b1.RevealStage2(lost1, bj1, c1.X, c2.X) + r2, p2 := b2.RevealStage2(lost2, bj2, c1.X, c2.X) + + if !b1.Commitment.VerifyStage2(bj1.StageCommitment, c1, bj1.StageReveal, r1, p1) { + t.Fatalf("b1 commitment failed to verify in stage1") + } + if !b2.Commitment.VerifyStage2(bj2.StageCommitment, c2, bj2.StageReveal, r2, p2) { + t.Fatalf("b2 commitment failed to verify in stage1") + } + + Z := Curve.Product(r1.Z, r2.Z) + if !Id.Equal(Z) { + t.Logf("Aha! Z[%d] != Id, new junction!", c) + junction = c + + if !lost1 && !b1.IsSet() { + t.Logf("setting lost1 to true") + lost1 = true + } + + if !lost2 && !b2.IsSet() { + t.Logf("setting lost2 to true") + lost2 = true + } + result |= 1 << (bitlength - 1 - c) + } + } + } + if result != bid1 { + t.Fatalf("wrong result: %05b", result) + } +} + +func TestFromPaper(t *testing.T) { + bitlength := 5 + vals := []int{ + 0b01001, + 0b01010, + 0b00111, + } + + t.Logf("testing bits: %05b, %05b, %05b", vals[0], vals[1], vals[2]) + + var bits = [3][]*Bit{} + for i, b := range vals { + bits[i] = int2bits(b, bitlength) + } + + var lost = [3]bool{} + instage1 := true + junction := -1 + result := 0 + + for idx := 0; idx < bitlength; idx++ { + var c = [3]*StageCommitment{} + var r = [3]*StageReveal{} + + for i, b := range bits { + c[i] = b[idx].StageCommit() + } + + if instage1 { + t.Logf("bit[%d] b1 = %t vs b2 = %t vs b3 = %t", idx, + bits[0][idx].IsSet(), bits[1][idx].IsSet(), bits[2][idx].IsSet()) + + var p = [3]*Stage1Proof{} + for i := range bits { + r[i], p[i] = bits[i][idx].RevealStage1(c[0].X, c[1].X, c[2].X) + t.Logf("bits[%d][%d] has sent %t", i, idx, bits[i][idx].Sent) + if !bits[i][idx].Commitment.VerifyStage1(c[i], r[i], p[i]) { + t.Fatalf("bits[%d][%d] commitment failed to verify in stage1", i, idx) + } + } + + Z := Curve.Product(r[0].Z, r[1].Z, r[2].Z) + if !Id.Equal(Z) { + t.Logf("Aha! Z[%d] != Id, switch to stage2", idx) + junction = idx + instage1 = false + + for i := range bits { + if !lost[i] && !bits[i][idx].IsSet() { + lost[i] = true + t.Logf("bit %d, set lost[%d] to true, so far: %v", idx, i, lost) + } + } + result |= 1 << (bitlength - 1 - idx) + } else { + t.Logf("Z[%d] == Id, staying in stage1", idx) + } + } else { + t.Logf("\nTesing bit[%d]:\n"+ + "set 0: %t\t1: %t\t2: %t\n"+ + "lost 0: %t\t1 %t\t2: %t\n", + idx, + bits[0][idx].IsSet(), bits[1][idx].IsSet(), bits[2][idx].IsSet(), + lost[0], lost[1], lost[2]) + + var bj = [3]*Bit{} + for i := range bits { + bj[i] = bits[i][junction] + } + + var p = [3]*Stage2Proof{} + for i := range bits { + r[i], p[i] = bits[i][idx].RevealStage2(lost[i], bj[i], c[0].X, c[1].X, c[2].X) + t.Logf("bits[%d][%d] has sent %t", i, idx, bits[i][idx].Sent) + if !bits[i][idx].Commitment.VerifyStage2(bj[i].StageCommitment, c[i], bj[i].StageReveal, r[i], p[i]) { + t.Fatalf("bits[%d][%d] commitment failed to verify in stage2, result so far: %05b", i, idx, result) + } + } + + Z := Curve.Product(r[0].Z, r[1].Z, r[2].Z) + if !Id.Equal(Z) { + t.Logf("Aha! Z[%d] != Id, new junction!", idx) + junction = idx + + for i := range bits { + if !lost[i] && !bits[i][idx].IsSet() { + lost[i] = true + t.Logf("bits[%d][%d], set lost[%d] to true, so far: %v", i, idx, i, lost) + } + } + result |= 1 << (bitlength - 1 - idx) + } + } + } + max := slices.Max(vals) + if result != max { + t.Fatalf("wrong result: %05b, expected: %05b", result, max) + } + +} + +/* +func TestRun3on5bit(t *testing.T) { runSeal(3, 5, t) } +func TestRun10on16bit(t *testing.T) { runSeal(10, 16, t) } +func TestRun100on16bit(t *testing.T) { runSeal(100, 16, t) } +*/ |