GithubHelp home page GithubHelp logo

whbjzzwjxq / ed25519-circom Goto Github PK

View Code? Open in Web Editor NEW

This project forked from electron-labs/ed25519-circom

0.0 0.0 0.0 107 KB

ED25519 implementation in Circom

Home Page: https://docs.electronlabs.org/

JavaScript 81.35% Makefile 0.19% Dockerfile 0.35% Solidity 18.11%

ed25519-circom's Introduction

Circom Ed25519

Twitter URL Build Status License

Curve operations and signature verification for Ed25519 digital signature scheme in circom

WARNING: This is a research project. It has not been audited and may contain bugs and security flaws. This implementation is NOT ready for production use.

https://docs.electronlabs.org/circom-ed25519/overview

The circuits follow the reference implementation from IETF RFC8032

Installing dependencies

  • npm install -g snarkjs
  • npm install
  • Clone and install circom - circom docs
  • If you want to build the verify circuit, you'll need to download a Powers of Tau file with 2^22 constraints and copy it into the circuits subdirectory of the project, with the name pot22_final.ptau. You can download Powers of Tau files from the Hermez trusted setup from this repository

Testing the build

  • You can run the entire testing suite (sans scalar multiplication and signature verification) using npm run test
  • You can test specific long running tests using npm run test-scalarmul or npm run test-verify

Benchmarks

All benchmarks were run on a 16-core 3.0GHz, 32G RAM machine (AWS c5a.4xlarge instance).

verify.circom
Constraints 2564061
Circuit compilation 72s
Witness generation 6s
Trusted setup phase 2 key generation 841s
Trusted setup phase 2 contribution 1040s
Proving key size 1.6G
Proving time (rapidsnark) 6s
Proof verification time 1s

Inputs

msg is the data for the signature

R8 is the first 256 bits of the signature (LSB to MSB)

S is the first 255 bits of the last 256 bits of the signature (LSB to MSB)

A is the public key in binary (LSB to MSB)

PointA is the point representing the public key on the elliptic curve (encoded in base 2^85 for brevity)

PointR is the point representing the R8 value on the elliptic curve (encoded in base 2^85)

The algorithm we follow only takes in A and R8 in binary form, and is decompressed to get PointA and PointR respectively. However, decompression is an expensive algorithm to perform in a circuit. On the other hand, compression is cheap and easy to implement. So, we use a nifty little trick to push the onus of providing both on the prover and perform equality checks after compressing the points within the circuit. Ref

You can find all helper functions to change encodings from well-known formats to circuit friendly formats here

Important Circuits

Modulus upto 2*(2^255-19) -> Mod2p

  # for input in
  def mod2p(in):
    diff = (2**255-19) - in
    return in if diff < 0 else diff
Available versions
  // ModulusAgainst2P
  // Elements are represented in binary
  (in: [256]) => (out: [255])

  // ModulusAgainst2Q
  // Elements are represented in binary
  (in: [254]) => (out: [253])

  // ModulusAgainst2PChunked51
  // Elements are represented in base 2^85
  (in: [4]) => (out: [3])

Modulus with 2^255-19 -> Modulus25519

  # for input `in` of unknown size, we explot that prime p
  # is close to a power of 2
  # input in broken down into an expression in = b + (p + 19)*c
  # where b is the least significant 255 bits of input and,
  # c is the rest of the bits. Then,
  # in mod p = (b + (p + 19)*c) mod p
  #          = (b mod p + 19*c mod p) mod p
  def mod25519(in):
    p = 2**255-19
    if in < p:
      return in
    b = in & ((1 << 255) - 1)
    c = in >> 255
    bmodp = mod2p(b)
    c19modp = mod25519(19*c)
    return mod2p(bmodp + c19modp)
Available versions
  // ModulusWith25519
  // Elements are represented in binary
  (a: [n]) => (out: [255])

  // ModulusWith252c
  // Elements are represented in binary
  (a: [n]) => (out: [253])

  // ModulusWith25519Chunked51
  // Elements are represented in base 2^85
  (a: [n]) => (out: [3])

Point Addition -> PointAdd

  # Add two points on Curve25519
  def point_add(P, Q):
    p = 2**255-19
    A, B = (P[1]-P[0]) * (Q[1]-Q[0]) % p, (P[1]+P[0]) * (Q[1]+Q[0]) % p
    C, D = 2 * P[3] * Q[3] * d % p, 2 * P[2] * Q[2] % p
    E, F, G, H = B-A, D-C, D+C, B+A
    return (E*F, G*H, F*G, E*H)
Available versions
  // PointAdd
  // Elements are represented in base 2^85
  (P: [4][3], Q: [4][3]) => (R: [4][3]) 

Scalar Multiplication -> ScalarMul

  # Multiply a point by scalar on Curve25519
  def point_mul(s, P):
    p = 2**255-19
    Q = (0, 1, 1, 0)  # Neutral element
    while s > 0:
      if s & 1:
        Q = point_add(Q, P)
      P = point_add(P, P)
      s >>= 1
    return Q
Available versions
  // ScalarMul
  // scalar value is represented in binary
  // Point elements are represented in base 2^85
  (s: [255], P: [4][3]) => (sP: [4][3]) 

Ed25519 Signature verification -> Verify

  def verify(msg, public, Rs, s, A, R):
    # Check that the compressed representation of a point 
    # equates to the paramaters extracted from signature
    assert(Rs == point_compress(R))
    assert(public == point_compress(A))
    h = sha512_modq(Rs + public + msg)
    sB = point_mul(s, G)
    hA = point_mul(h, A)
    return point_equal(sB, point_add(R, hA))
Available versions
  // out signal value is 0 or 1 depending on whether the signature validation failed or passed
  (msg: [n], A: [256], R8: [256], S: [255], PointA: [4][3], PointR: [4][3]) => (out);

ed25519-circom's People

Contributors

electron-team avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.