-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Move low-level operations to JS #967
Changes from all commits
933455f
f89ce6d
e5786a2
3e3998b
633e621
822baa4
574b267
354e0a5
3f7276a
61ea3c1
ae68c1c
072557d
d145b0b
f412241
fa47f32
e358157
bce7d29
925f16e
54c32a1
edc88a1
8c3b50f
11913a8
d937a1e
6e80437
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,46 @@ | ||
import { | ||
shutdown, | ||
isReady, | ||
Field, | ||
Bool, | ||
Circuit, | ||
Group, | ||
Scalar, | ||
Provable, | ||
} from 'snarkyjs'; | ||
import { Bool, Group, Scalar, Provable } from 'snarkyjs'; | ||
|
||
describe('group', () => { | ||
let g = Group({ | ||
x: -1, | ||
y: 2, | ||
}); | ||
beforeAll(async () => { | ||
await isReady; | ||
}); | ||
|
||
afterAll(async () => { | ||
setTimeout(async () => { | ||
await shutdown(); | ||
}, 0); | ||
}); | ||
|
||
describe('Inside circuit', () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we use the quickcheck generator Gregor made earlier to check some of the algebraic properties for edge cases? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking about that as well, however, I think there is no easy way to sample valid Group elements other than brute forcing (or is there?) that's why the existing tests mostly work with the generator and There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I used to sample public keys (= group elements) by picking a random private key (= scalar) and scaling the group generator with it. However, now we have hashToCurve which should be faster, especially if you skip the hash and only do random field element + mapToCurve There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh right, I didn't consider that at all 😵💫 I'll add some more tests, just to be sure! |
||
describe('group membership', () => { | ||
it('valid element does not throw', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
Provable.witness(Group, () => g); | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('valid element does not throw', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
Provable.witness(Group, () => Group.generator); | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('Group.zero element does not throw', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
Provable.witness(Group, () => Group.zero); | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('invalid group element throws', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
Provable.witness(Group, () => Group({ x: 2, y: 2 })); | ||
}); | ||
}).toThrow(); | ||
}); | ||
}); | ||
|
||
describe('add', () => { | ||
it('g+g does not throw', () => { | ||
expect(() => { | ||
|
@@ -35,6 +51,55 @@ describe('group', () => { | |
}); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('g+zero = g', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
const x = Provable.witness(Group, () => g); | ||
const zero = Provable.witness(Group, () => Group.zero); | ||
x.add(zero).assertEquals(x); | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('zero+g = g', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
const x = Provable.witness(Group, () => g); | ||
const zero = Provable.witness(Group, () => Group.zero); | ||
zero.add(x).assertEquals(x); | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('g+(-g) = zero', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
const x = Provable.witness(Group, () => g); | ||
const zero = Provable.witness(Group, () => Group.zero); | ||
x.add(x.neg()).assertEquals(zero); | ||
Trivo25 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('(-g)+g = zero', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
const x = Provable.witness(Group, () => g); | ||
const zero = Provable.witness(Group, () => Group.zero); | ||
x.neg().add(x).assertEquals(zero); | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
Trivo25 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
it('zero + zero = zero', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
const zero = Provable.witness(Group, () => Group.zero); | ||
zero.add(zero).assertEquals(zero); | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
}); | ||
|
||
describe('sub', () => { | ||
|
@@ -49,6 +114,35 @@ describe('group', () => { | |
}); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('g-zero = g', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
const x = Provable.witness(Group, () => g); | ||
const zero = Provable.witness(Group, () => Group.zero); | ||
x.sub(zero).assertEquals(x); | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('zero - g = -g', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
const x = Provable.witness(Group, () => g); | ||
const zero = Provable.witness(Group, () => Group.zero); | ||
zero.sub(x).assertEquals(x.neg()); | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('zero - zero = zero', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
const zero = Provable.witness(Group, () => Group.zero); | ||
zero.sub(zero).assertEquals(zero); | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
}); | ||
|
||
describe('neg', () => { | ||
|
@@ -60,6 +154,15 @@ describe('group', () => { | |
}); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('neg(zero) = zero', () => { | ||
expect(() => { | ||
Provable.runAndCheck(() => { | ||
const zero = Provable.witness(Group, () => Group.zero); | ||
zero.neg().assertEquals(zero); | ||
}); | ||
}).not.toThrow(); | ||
}); | ||
}); | ||
|
||
describe('scale', () => { | ||
|
@@ -161,6 +264,13 @@ describe('group', () => { | |
g.neg(); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('zero.neg = zero', () => { | ||
expect(() => { | ||
const zero = Group.zero; | ||
zero.neg().assertEquals(zero); | ||
}).not.toThrow(); | ||
}); | ||
}); | ||
|
||
describe('add', () => { | ||
|
@@ -169,6 +279,41 @@ describe('group', () => { | |
g.add(g); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('g + zero = g', () => { | ||
expect(() => { | ||
const zero = Group.zero; | ||
g.add(zero).assertEquals(g); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('zero + g = g', () => { | ||
expect(() => { | ||
const zero = Group.zero; | ||
zero.add(g).assertEquals(g); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('g + (-g) = zero', () => { | ||
expect(() => { | ||
const zero = Group.zero; | ||
g.add(g.neg()).assertEquals(zero); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('(-g) + g = zero', () => { | ||
expect(() => { | ||
const zero = Group.zero; | ||
g.neg().add(g).assertEquals(zero); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('zero + zero = zero', () => { | ||
expect(() => { | ||
const zero = Group.zero; | ||
zero.add(zero).assertEquals(zero); | ||
}).not.toThrow(); | ||
}); | ||
}); | ||
|
||
describe('sub', () => { | ||
|
@@ -177,6 +322,27 @@ describe('group', () => { | |
Group.generator.sub(g); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('g - zero = g', () => { | ||
expect(() => { | ||
const zero = Group.zero; | ||
g.sub(zero).assertEquals(g); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('zero - g = -g', () => { | ||
expect(() => { | ||
const zero = Group.zero; | ||
zero.sub(g).assertEquals(g.neg()); | ||
}).not.toThrow(); | ||
}); | ||
|
||
it('zero - zero = -zero', () => { | ||
expect(() => { | ||
const zero = Group.zero; | ||
zero.sub(zero).assertEquals(zero); | ||
}).not.toThrow(); | ||
}); | ||
}); | ||
|
||
describe('scale', () => { | ||
|
@@ -231,18 +397,20 @@ describe('group', () => { | |
y.assertEquals(z); | ||
}); | ||
}); | ||
|
||
it('sub', () => { | ||
let y = Provable.witness(Group, () => g).sub( | ||
Provable.witness(Group, () => Group.generator) | ||
); | ||
let z = g.sub(Group.generator); | ||
y.assertEquals(z); | ||
}); | ||
|
||
it('sub', () => { | ||
let y = Provable.witness(Group, () => g).assertEquals( | ||
Provable.witness(Group, () => g) | ||
); | ||
let z = g.assertEquals(g); | ||
g.assertEquals(g); | ||
}); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you explain this blowup in
Group.equals()
constraints @Trivo25?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it just caused by the added constraints in
check()
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
Group Primitive.equals
check bundles a couple additional equality checks than just a simpleequals()
, it does the following:So its calling
equals
multiple times, which blows up the constraints a bit more. The singleequals
constraints aren't that bad, just inflated by the batch. The additional constraints come fromzero
-related checks (such as.check
)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah I understand that it has more, but the only thing that changed in that circuit should be
check()
andequals()
, so I was wondering what explains the increase in circuit size compared to the previous versionThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea, its the change in
check