Dash Core  0.12.2.1
P2P Digital Currency
schnorr_impl.h
Go to the documentation of this file.
1 /***********************************************************************
2  * Copyright (c) 2014-2015 Pieter Wuille *
3  * Distributed under the MIT software license, see the accompanying *
4  * file COPYING or http://www.opensource.org/licenses/mit-license.php. *
5  ***********************************************************************/
6 
7 #ifndef _SECP256K1_SCHNORR_IMPL_H_
8 #define _SECP256K1_SCHNORR_IMPL_H_
9 
10 #include <string.h>
11 
12 #include "schnorr.h"
13 #include "num.h"
14 #include "field.h"
15 #include "group.h"
16 #include "ecmult.h"
17 #include "ecmult_gen.h"
18 
62 static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context* ctx, unsigned char *sig64, const secp256k1_scalar *key, const secp256k1_scalar *nonce, const secp256k1_ge *pubnonce, secp256k1_schnorr_msghash hash, const unsigned char *msg32) {
63  secp256k1_gej Rj;
64  secp256k1_ge Ra;
65  unsigned char h32[32];
66  secp256k1_scalar h, s;
67  int overflow;
69 
71  return 0;
72  }
73  n = *nonce;
74 
75  secp256k1_ecmult_gen(ctx, &Rj, &n);
76  if (pubnonce != NULL) {
77  secp256k1_gej_add_ge(&Rj, &Rj, pubnonce);
78  }
79  secp256k1_ge_set_gej(&Ra, &Rj);
81  if (secp256k1_fe_is_odd(&Ra.y)) {
82  /* R's y coordinate is odd, which is not allowed (see rationale above).
83  Force it to be even by negating the nonce. Note that this even works
84  for multiparty signing, as the R point is known to all participants,
85  which can all decide to flip the sign in unison, resulting in the
86  overall R point to be negated too. */
88  }
90  secp256k1_fe_get_b32(sig64, &Ra.x);
91  hash(h32, sig64, msg32);
92  overflow = 0;
93  secp256k1_scalar_set_b32(&h, h32, &overflow);
94  if (overflow || secp256k1_scalar_is_zero(&h)) {
96  return 0;
97  }
98  secp256k1_scalar_mul(&s, &h, key);
100  secp256k1_scalar_add(&s, &s, &n);
102  secp256k1_scalar_get_b32(sig64 + 32, &s);
103  return 1;
104 }
105 
106 static int secp256k1_schnorr_sig_verify(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, const secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32) {
107  secp256k1_gej Qj, Rj;
108  secp256k1_ge Ra;
109  secp256k1_fe Rx;
110  secp256k1_scalar h, s;
111  unsigned char hh[32];
112  int overflow;
113 
114  if (secp256k1_ge_is_infinity(pubkey)) {
115  return 0;
116  }
117  hash(hh, sig64, msg32);
118  overflow = 0;
119  secp256k1_scalar_set_b32(&h, hh, &overflow);
120  if (overflow || secp256k1_scalar_is_zero(&h)) {
121  return 0;
122  }
123  overflow = 0;
124  secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow);
125  if (overflow) {
126  return 0;
127  }
128  if (!secp256k1_fe_set_b32(&Rx, sig64)) {
129  return 0;
130  }
131  secp256k1_gej_set_ge(&Qj, pubkey);
132  secp256k1_ecmult(ctx, &Rj, &Qj, &h, &s);
133  if (secp256k1_gej_is_infinity(&Rj)) {
134  return 0;
135  }
136  secp256k1_ge_set_gej_var(&Ra, &Rj);
138  if (secp256k1_fe_is_odd(&Ra.y)) {
139  return 0;
140  }
141  return secp256k1_fe_equal_var(&Rx, &Ra.x);
142 }
143 
144 static int secp256k1_schnorr_sig_recover(const secp256k1_ecmult_context* ctx, const unsigned char *sig64, secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32) {
145  secp256k1_gej Qj, Rj;
146  secp256k1_ge Ra;
147  secp256k1_fe Rx;
148  secp256k1_scalar h, s;
149  unsigned char hh[32];
150  int overflow;
151 
152  hash(hh, sig64, msg32);
153  overflow = 0;
154  secp256k1_scalar_set_b32(&h, hh, &overflow);
155  if (overflow || secp256k1_scalar_is_zero(&h)) {
156  return 0;
157  }
158  overflow = 0;
159  secp256k1_scalar_set_b32(&s, sig64 + 32, &overflow);
160  if (overflow) {
161  return 0;
162  }
163  if (!secp256k1_fe_set_b32(&Rx, sig64)) {
164  return 0;
165  }
166  if (!secp256k1_ge_set_xo_var(&Ra, &Rx, 0)) {
167  return 0;
168  }
169  secp256k1_gej_set_ge(&Rj, &Ra);
171  secp256k1_scalar_negate(&s, &s);
172  secp256k1_scalar_mul(&s, &s, &h);
173  secp256k1_ecmult(ctx, &Qj, &Rj, &h, &s);
174  if (secp256k1_gej_is_infinity(&Qj)) {
175  return 0;
176  }
177  secp256k1_ge_set_gej(pubkey, &Qj);
178  return 1;
179 }
180 
181 static int secp256k1_schnorr_sig_combine(unsigned char *sig64, size_t n, const unsigned char * const *sig64ins) {
182  secp256k1_scalar s = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
183  size_t i;
184  for (i = 0; i < n; i++) {
185  secp256k1_scalar si;
186  int overflow;
187  secp256k1_scalar_set_b32(&si, sig64ins[i] + 32, &overflow);
188  if (overflow) {
189  return -1;
190  }
191  if (i) {
192  if (memcmp(sig64ins[i - 1], sig64ins[i], 32) != 0) {
193  return -1;
194  }
195  }
196  secp256k1_scalar_add(&s, &s, &si);
197  }
198  if (secp256k1_scalar_is_zero(&s)) {
199  return 0;
200  }
201  memcpy(sig64, sig64ins[0], 32);
202  secp256k1_scalar_get_b32(sig64 + 32, &s);
204  return 1;
205 }
206 
207 #endif
static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b)
static int secp256k1_ge_is_infinity(const secp256k1_ge *a)
static int secp256k1_gej_is_infinity(const secp256k1_gej *a)
static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context *ctx, secp256k1_gej *r, const secp256k1_scalar *a)
static void secp256k1_fe_normalize_var(secp256k1_fe *r)
static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a)
Definition: group_impl.h:65
static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a)
static int secp256k1_scalar_is_zero(const secp256k1_scalar *a)
static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng)
static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow)
static int secp256k1_fe_is_odd(const secp256k1_fe *a)
static int secp256k1_schnorr_sig_sign(const secp256k1_ecmult_gen_context *ctx, unsigned char *sig64, const secp256k1_scalar *key, const secp256k1_scalar *nonce, const secp256k1_ge *pubnonce, secp256k1_schnorr_msghash hash, const unsigned char *msg32)
Definition: schnorr_impl.h:62
static int secp256k1_schnorr_sig_combine(unsigned char *sig64, size_t n, const unsigned char *const *sig64ins)
Definition: schnorr_impl.h:181
#define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0)
Definition: scalar_4x64.h:17
static secp256k1_context * ctx
Definition: tests.c:42
static void secp256k1_ge_set_gej(secp256k1_ge *r, secp256k1_gej *a)
static void secp256k1_scalar_clear(secp256k1_scalar *r)
secp256k1_fe x
Definition: group.h:15
static int secp256k1_schnorr_sig_recover(const secp256k1_ecmult_context *ctx, const unsigned char *sig64, secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32)
Definition: schnorr_impl.h:144
static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar *a)
static int secp256k1_ge_set_xo_var(secp256k1_ge *r, const secp256k1_fe *x, int odd)
static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a)
static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b)
static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b)
static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *a)
void * memcpy(void *a, const void *b, size_t c)
static void secp256k1_fe_normalize(secp256k1_fe *r)
void(* secp256k1_schnorr_msghash)(unsigned char *h32, const unsigned char *r32, const unsigned char *msg32)
Definition: schnorr.h:13
static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a)
static void secp256k1_gej_add_ge(secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_ge *b)
static void secp256k1_gej_set_ge(secp256k1_gej *r, const secp256k1_ge *a)
secp256k1_fe y
Definition: group.h:16
static int secp256k1_schnorr_sig_verify(const secp256k1_ecmult_context *ctx, const unsigned char *sig64, const secp256k1_ge *pubkey, secp256k1_schnorr_msghash hash, const unsigned char *msg32)
Definition: schnorr_impl.h:106