Navigation Menu

Skip to content
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

Make sqrt_flagged more deterministic #2239

Merged
merged 2 commits into from Apr 15, 2019
Merged

Make sqrt_flagged more deterministic #2239

merged 2 commits into from Apr 15, 2019

Conversation

imeckler
Copy link
Member

This PR makes sqrt flagged more deterministic by using a trick I learned from Dan Boneh for how to witness non-squareness. The trick is the following. First, fix a non-square m. Then for any x in F, x is a non-square iff m*x is a square. Thus, if you want to show that x is not a square, you can simply show that mx is a non-square, which you can do by witnessing the square root.

The square_root flagged function is semantically

x -> if is_square x then (sqrt x, true) else (undefined_behavior, false)

We implement this with a snarky program as follows (prover blocks omitted):

let sqrt_exn x =
  let y = exists Field.typ in
  assert_square y x;
  y

let sqrt_flagged x =
  let b = exists Boolean.typ in
  ( sqrt_exn (if b then x else m * x)
  , b )

We verify the correctness as follows:

If e is an expression let ⟦ e ⟧ denote the set of possible values e can evaluate to over all choices of non-determinism which do not cause an assertion failure.

Two lemmas claimed without proof:

Lemma: If a is a square then ⟦ sqrt_exn a ⟧ = { sqrt a }

Lemma: If x is not a square then ⟦ sqrt_exn a ⟧ = { }

Now let's show

Proposition: sqrt_flagged implements the intended semantics.

We have

⟦ sqrt_flagged x ⟧
=
  ⟦ (sqrt_exn (if true then x else m * x), true) ⟧
  ∪
  ⟦ (sqrt_exn (if false then x else m * x), false) ⟧
=
  ⟦ (sqrt_exn x, true) ⟧
  ∪
  ⟦ (sqrt_exn (m * x), false) ⟧
=
  ⟦ (sqrt_exn x, true) ⟧
  ∪
  ⟦ (sqrt_exn (m * x), false) ⟧

If x is a square then mx is not a square so we have

⟦ sqrt_flagged x ⟧
= ⟦ (sqrt_exn x, true) ⟧ ∪ ⟦ (sqrt_exn (m * x), false) ⟧
= { (sqrt x, true) } ∪ {}
= { (sqrt x, true) }

On the other hand if x is not a square, then mx is a square so we have

⟦ sqrt_flagged x ⟧
= ⟦ (sqrt_exn x, true) ⟧ ∪ ⟦ (sqrt_exn (m * x), false) ⟧
= {} ∪ { (sqrt (m * x), false) }
= { (sqrt (m * x), false) }

which evidently matches the claimed semantics.

@imeckler imeckler requested a review from rbkhmrcr April 13, 2019 04:10
@imeckler imeckler added the ready-to-merge Adding this label will trigger mergify and trigger CI to run and merge the PR label Apr 15, 2019
@mergify mergify bot merged commit a986d8b into master Apr 15, 2019
@mergify mergify bot deleted the fix/sqrt-flagged branch April 15, 2019 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-to-merge Adding this label will trigger mergify and trigger CI to run and merge the PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants