Switch commitments in libsecp fork (#109)

* first pass at switch committment generator
* create sage generator script
This commit is contained in:
Yeastplume 2017-08-29 17:27:01 +01:00 committed by Ignotus Peverell
parent 9c649edfbf
commit b5e62c81c0
12 changed files with 153 additions and 6 deletions

View file

@ -457,6 +457,7 @@ impl Block {
let msg = try!(secp::Message::from_slice(&[0; secp::constants::MESSAGE_SIZE]));
let sig = try!(secp.sign(&msg, &skey));
let commit = secp.commit(REWARD, skey).unwrap();
//let switch_commit = secp.switch_commit(skey).unwrap();
let rproof = secp.range_proof(0, REWARD, skey, commit);
let output = Output {

View file

@ -72,7 +72,7 @@ cuckoo_miner_async_mode = false
#if not specified, grin will look in the directory /deps relative
#to the executable
#cuckoo_miner_plugin_dir = "target/debug/deps"
#cuckoo_miner_plugin_dir = "target/debug/plugins"
#if using cuckoo_miner, the implementation to use.. currently
#just filters for this word in the filenames in the plugin

View file

@ -0,0 +1,34 @@
import sys
import hashlib
from sage.all import *
for t in xrange(1023, -1, -1):
p = 2**256 -2**32 - t
if p.is_prime():
print '%x'%p
break
a = 0
b = 7
F = FiniteField(p)
o = '%x' % (EllipticCurve ([F (a), F(b)]).order())
print o
gen2 = hashlib.sha256('0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'.decode('hex'))
gH = EllipticCurve ([F (0), F(7)]).lift_x(int(gen2.hexdigest(),16))
print 'gH: %s' % gH
gen_h = '%x %x'%gH.xy()
print 'GENERATOR H: %s'%gen_h
#this doesn't create a point on the curve
#gen_j_input = '04%x%x'%gG.xy()
#this does
gen_j_input = gen2.hexdigest()
print 'gen_j_input: %s'%gen_j_input
gen3 = hashlib.sha256(gen_j_input.decode('hex'))
gJ = EllipticCurve ([F (0), F(7)]).lift_x(int(gen3.hexdigest(),16))
print 'gJ: %s' % gJ
gen_j = '%x %x'%gJ.xy()
print 'GENERATOR J: %s'%gen_j

View file

@ -10,9 +10,41 @@
#include "modules/rangeproof/pedersen_impl.h"
#include "modules/rangeproof/borromean_impl.h"
#include "modules/rangeproof/rangeproof_impl.h"
#include "modules/rangeproof/switch_impl.h"
void secp256k1_switch_context_initialize(secp256k1_context* ctx) {
secp256k1_pedersen_context_build(&ctx->switch_ctx, secp256k1_ge_const_g3, &ctx->error_callback);
}
/* Generates a simple switch commitment: *commit = blind * G3. The commitment is 33 bytes, the blinding factor is 32 bytes.*/
int secp256k1_switch_commit(const secp256k1_context* ctx, unsigned char *commit, unsigned char *blind) {
secp256k1_gej rj;
secp256k1_ge r;
secp256k1_scalar sec;
size_t sz;
int overflow;
int ret = 0;
ARG_CHECK(ctx != NULL);
ARG_CHECK(secp256k1_pedersen_context_is_built(&ctx->switch_ctx));
ARG_CHECK(commit != NULL);
ARG_CHECK(blind != NULL);
secp256k1_scalar_set_b32(&sec, blind, &overflow);
if (!overflow) {
secp256k1_switch_ecmult(&ctx->switch_ctx, &rj, &sec);
if (!secp256k1_gej_is_infinity(&rj)) {
secp256k1_ge_set_gej(&r, &rj);
sz = 33;
ret = secp256k1_eckey_pubkey_serialize(&r, commit, &sz, 1);
}
secp256k1_gej_clear(&rj);
secp256k1_ge_clear(&r);
}
secp256k1_scalar_clear(&sec);
return ret;
}
void secp256k1_pedersen_context_initialize(secp256k1_context* ctx) {
secp256k1_pedersen_context_build(&ctx->pedersen_ctx, &ctx->error_callback);
secp256k1_pedersen_context_build(&ctx->pedersen_ctx, secp256k1_ge_const_g2, &ctx->error_callback);
}
/* Generates a pedersen commitment: *commit = blind * G + value * G2. The commitment is 33 bytes, the blinding factor is 32 bytes.*/

View file

@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2014, 2015 Gregory Maxwell *
* Copyright (c) 2014, 2015 Gregory Maxwell *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
@ -17,7 +17,8 @@ typedef struct {
} secp256k1_pedersen_context;
static void secp256k1_pedersen_context_init(secp256k1_pedersen_context* ctx);
static void secp256k1_pedersen_context_build(secp256k1_pedersen_context* ctx, const secp256k1_callback* cb);
static void secp256k1_pedersen_context_build(secp256k1_pedersen_context* ctx, const secp256k1_ge ge,
const secp256k1_callback* cb);
static void secp256k1_pedersen_context_clone(secp256k1_pedersen_context *dst,
const secp256k1_pedersen_context* src, const secp256k1_callback* cb);
static void secp256k1_pedersen_context_clear(secp256k1_pedersen_context* ctx);

View file

@ -13,6 +13,7 @@
* sage: G2 = EllipticCurve ([F (0), F (7)]).lift_x(int(hashlib.sha256('0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'.decode('hex')).hexdigest(),16))
* sage: '%x %x'%G2.xy()
*/
static const secp256k1_ge secp256k1_ge_const_g2 = SECP256K1_GE_CONST(
0x50929b74UL, 0xc1a04954UL, 0xb78b4b60UL, 0x35e97a5eUL,
0x078a5a0fUL, 0x28ec96d5UL, 0x47bfee9aUL, 0xce803ac0UL,
@ -24,7 +25,7 @@ static void secp256k1_pedersen_context_init(secp256k1_pedersen_context *ctx) {
ctx->prec = NULL;
}
static void secp256k1_pedersen_context_build(secp256k1_pedersen_context *ctx, const secp256k1_callback *cb) {
static void secp256k1_pedersen_context_build(secp256k1_pedersen_context *ctx, const secp256k1_ge ge, const secp256k1_callback *cb) {
secp256k1_ge prec[256];
secp256k1_gej gj;
secp256k1_gej nums_gej;
@ -37,7 +38,7 @@ static void secp256k1_pedersen_context_build(secp256k1_pedersen_context *ctx, co
ctx->prec = (secp256k1_ge_storage (*)[16][16])checked_malloc(cb, sizeof(*ctx->prec));
/* get the generator */
secp256k1_gej_set_ge(&gj, &secp256k1_ge_const_g2);
secp256k1_gej_set_ge(&gj, &ge);
/* Construct a group element with no known corresponding scalar (nothing up my sleeve). */
{

View file

@ -0,0 +1,19 @@
/**********************************************************************
* Copyright (c) 2014, 2017 Gregory Maxwell *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php.*
**********************************************************************/
#ifndef _SECP256K1_SWITCH_H_
#define _SECP256K1_SWITCH_H_
#include "group.h"
#include "scalar.h"
#include <stdint.h>
/* sec * G3. */
static void secp256k1_switch_ecmult(const secp256k1_pedersen_context *switch_ctx,
secp256k1_gej *rj,
const secp256k1_scalar *sec);
#endif

View file

@ -0,0 +1,35 @@
/***********************************************************************
* Copyright (c) 2017 Gregory Maxwell *
* Distributed under the MIT software license, see the accompanying *
* file COPYING or http://www.opensource.org/licenses/mit-license.php. *
***********************************************************************/
#ifndef _SECP256K1_SWITCH_IMPL_H_
#define _SECP256K1_SWITCH_IMPL_H_
#include "switch.h"
/** Alternative-alternative generator for secp256k1.
* This is the sha256 of the sha256 of 'g' after DER encoding (without compression),
* which happens to be a point on the curve.
* sage: gen_h = hashlib.sha256('0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8'.decode('hex'))
* sage: gen_j_input = gen_h.hexdigest()
* sage: gen_j = hashlib.sha256(gen_j_input.decode('hex'))
* sage: G3 = EllipticCurve ([F (0), F (7)]).lift_x(int(gen_j.hexdigest(),16))
* sage: '%x %x'%G3.xy()
*/
static const secp256k1_ge secp256k1_ge_const_g3 = SECP256K1_GE_CONST(
0xb860f567UL, 0x95fc03f3UL, 0xc2168538UL, 0x3d1b5a2fUL,
0x2954f49bUL, 0x7e398b8dUL, 0x2a019393UL, 0x3621155fUL,
0x5bc0f62cUL, 0xd35570acUL, 0xbdc0bd8bUL, 0xfc5a95ceUL,
0x9a5a5965UL, 0x8b30a903UL, 0xa6fe5d22UL, 0x593a37f5UL
);
/* sec * G3 */
SECP256K1_INLINE static void secp256k1_switch_ecmult(const secp256k1_pedersen_context *switch_ctx,
secp256k1_gej *rj, const secp256k1_scalar *sec) {
secp256k1_pedersen_ecmult_small(switch_ctx, rj, sec);
}
#endif

View file

@ -58,6 +58,7 @@ struct secp256k1_context_struct {
secp256k1_ecmult_gen_context ecmult_gen_ctx;
#ifdef ENABLE_MODULE_RANGEPROOF
secp256k1_pedersen_context pedersen_ctx;
secp256k1_pedersen_context switch_ctx;
secp256k1_rangeproof_context rangeproof_ctx;
#endif
secp256k1_callback illegal_callback;

View file

@ -137,6 +137,7 @@ extern "C" {
pub fn secp256k1_context_randomize(cx: *mut Context, seed32: *const c_uchar) -> c_int;
pub fn secp256k1_pedersen_context_initialize(ctx: *mut Context);
pub fn secp256k1_switch_context_initialize(ctx: *mut Context);
pub fn secp256k1_rangeproof_context_initialize(ctx: *mut Context);
// TODO secp256k1_context_set_illegal_callback
@ -292,6 +293,13 @@ extern "C" {
scalar: *const c_uchar)
-> c_int;
// Generates a switch commitment: *commit = blind * J
// The commitment is 33 bytes, the blinding factor is 32 bytes.
pub fn secp256k1_switch_commit(ctx: *const Context,
commit: *mut c_uchar,
blind: *const c_uchar)
-> c_int;
// Generates a pedersen commitment: *commit = blind * G + value * G2.
// The commitment is 33 bytes, the blinding factor is 32 bytes.
pub fn secp256k1_pedersen_commit(ctx: *const Context,

View file

@ -462,6 +462,7 @@ impl Secp256k1 {
if caps == ContextFlag::Commit {
unsafe {
ffi::secp256k1_pedersen_context_initialize(ctx);
ffi::secp256k1_switch_context_initialize(ctx);
ffi::secp256k1_rangeproof_context_initialize(ctx);
}
}

View file

@ -199,6 +199,20 @@ impl ::std::fmt::Debug for RangeProof {
}
impl Secp256k1 {
/// Creates a switch commitment from a blinding factor
pub fn switch_commit(&self, blind: SecretKey) -> Result<Commitment, Error> {
if self.caps != ContextFlag::Commit {
return Err(Error::IncapableContext);
}
let mut commit = [0; 33];
unsafe {
ffi::secp256k1_switch_commit(self.ctx, commit.as_mut_ptr(), blind.as_ptr())
};
Ok(Commitment(commit))
}
/// Creates a pedersen commitment from a value and a blinding factor
pub fn commit(&self, value: u64, blind: SecretKey) -> Result<Commitment, Error> {