I see it differently #[0] #[1] .

(1) Miners arw being paid for a block size whether its full or empty, a block is a block,

(2) sats are a legitimate form of payment the same as "This Note is legal tender for all debts public or private" listed on cash bills and used the smae as an exchange of funds between individuals outside of the banking network, and

(3) sats are now a form of "cash."

cc: #[2] #[3]

Reply to this note

Please Login to reply.

Discussion

This is what you guys need to worry about instead of ordinals (cc: #[3] #[6] #[4] #[1] #[2] #[7] ) 😉

"The private key

* MUST be set before generating the signature itself, but message

* data can be input before setting the key.

*

* Instances are NOT thread-safe. However, once a signature has

* been generated, the same instance can be used again for another

* signature; {@link #setPrivateKey} need not be called again if the

* private key has not changed. {@link #reset} can also be called to

* cancel previously input data. Generating a signature with {@link

* #sign} (not {@link #signHash}) also implicitly causes a

* reset.

*

* Redistribution and use in source and binary forms, with or without

* modification, is permitted pursuant to, and subject to the license

* terms contained in, the Simplified BSD License set forth in Section

* 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents

* (http://trustee.ietf.org/license-info)."

https://www.rfc-editor.org/rfc/rfc6979

A.3. Sample Code

We include here a sample implementation of deterministic DSA. It is

meant for illustration purposes; for instance, this code makes no

attempt at avoiding side-channel leakage of the private key. It is

written in the Java programming language. The actual generation of

the "random" value k is done in the computek() method. The Java

virtual machine (JVM) is assumed to provide the implementation of the

hash function and of HMAC.

// ==================================================================

import java.math.BigInteger;

import java.security.InvalidKeyException;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;

import javax.crypto.spec.SecretKeySpec;

/**

* Deterministic DSA signature generation. This is a sample

* implementation designed to illustrate how deterministic DSA

* chooses the pseudorandom value k when signing a given message.

* This implementation was NOT optimized or hardened against

* side-channel leaks.

*

* An instance is created with a hash function name, which must be

* supported by the underlying Java virtual machine ("SHA-1" and

* "SHA-256" should work everywhere). The data to sign is input

* through the {@code update()} methods. The private key is set with

* {@link #setPrivateKey}. The signature is obtained by calling

* {@link #sign}; alternatively, {@link #signHash} can be used to

* sign some data that has been externally hashed. The private key

* MUST be set before generating the signature itself, but message

* data can be input before setting the key.

*

* Instances are NOT thread-safe. However, once a signature has

* been generated, the same instance can be used again for another

* signature; {@link #setPrivateKey} need not be called again if the

* private key has not changed. {@link #reset} can also be called to

* cancel previously input data. Generating a signature with {@link

* #sign} (not {@link #signHash}) also implicitly causes a

* reset.

*

* ------------------------------------------------------------------

* Copyright (c) 2013 IETF Trust and the persons identified as

* authors of the code. All rights reserved.

*

Pornin Informational [Page 70]

RFC 6979 Deterministic DSA and ECDSA August 2013

* Redistribution and use in source and binary forms, with or without

* modification, is permitted pursuant to, and subject to the license

* terms contained in, the Simplified BSD License set forth in Section

* 4.c of the IETF Trust's Legal Provisions Relating to IETF Documents

* (http://trustee.ietf.org/license-info).

*

* Technical remarks and questions can be addressed to:

* pornin@bolet.org

* ------------------------------------------------------------------

*/

public class DeterministicDSA {

private String macName;

private MessageDigest dig;

private Mac hmac;

private BigInteger p, q, g, x;

private int qlen, rlen, rolen, holen;

private byte[] bx;

/**

* Create an instance, using the specified hash function.

* The name is used to obtain from the JVM an implementation

* of the hash function and an implementation of HMAC.

*

* @param hashName the hash function name

* @throws IllegalArgumentException on unsupported name

*/

public DeterministicDSA(String hashName)

{

try {

dig = MessageDigest.getInstance(hashName);

} catch (NoSuchAlgorithmException nsae) {

throw new IllegalArgumentException(nsae);

}

if (hashName.indexOf('-') < 0) {

macName = "Hmac" + hashName;

} else {

StringBuilder sb = new StringBuilder();

sb.append("Hmac");

int n = hashName.length();

for (int i = 0; i < n; i ++) {

char c = hashName.charAt(i);

if (c != '-') {

sb.append(c);

}

}

macName = sb.toString();

Pornin Informational [Page 71]

RFC 6979 Deterministic DSA and ECDSA August 2013

}

try {

hmac = Mac.getInstance(macName);

} catch (NoSuchAlgorithmException nsae) {

throw new IllegalArgumentException(nsae);

}

holen = hmac.getMacLength();

}

/**

* Set the private key.

*

* @param p key parameter: field modulus

* @param q key parameter: subgroup order

* @param g key parameter: generator

* @param x private key

*/

public void setPrivateKey(BigInteger p, BigInteger q,

BigInteger g, BigInteger x)

{

/*

* Perform some basic sanity checks. We do not

* check primality of p or q because that would

* be too expensive.

*

* We reject keys where q is longer than 999 bits,

* because it would complicate signature encoding.

* Normal DSA keys do not have a q longer than 256

* bits anyway.

*/

if (p == null || q == null || g == null || x == null

|| p.signum() <= 0 || q.signum() <= 0

|| g.signum() <= 0 || x.signum() <= 0

|| x.compareTo(q) >= 0 || q.compareTo(p) >= 0

|| q.bitLength() > 999

|| g.compareTo(p) >= 0 || g.bitLength() == 1

|| g.modPow(q, p).bitLength() != 1) {

throw new IllegalArgumentException(

"invalid DSA private key");

}

this.p = p;

this.q = q;

this.g = g;

this.x = x;

qlen = q.bitLength();

if (q.signum() <= 0 || qlen < 8) {

throw new IllegalArgumentException(

"bad group order: " + q);

Pornin Informational [Page 72]

RFC 6979 Deterministic DSA and ECDSA August 2013

}

rolen = (qlen + 7) >>> 3;

rlen = rolen * 8;

/*

* Convert the private exponent (x) into a sequence

* of octets.

*/

bx = int2octets(x);

}

private BigInteger bits2int(byte[] in)

{

BigInteger v = new BigInteger(1, in);

int vlen = in.length * 8;

if (vlen > qlen) {

v = v.shiftRight(vlen - qlen);

}

return v;

}

private byte[] int2octets(BigInteger v)

{

byte[] out = v.toByteArray();

if (out.length < rolen) {

byte[] out2 = new byte[rolen];

System.arraycopy(out, 0,

out2, rolen - out.length,

out.length);

return out2;

} else if (out.length > rolen) {

byte[] out2 = new byte[rolen];

System.arraycopy(out, out.length - rolen,

out2, 0, rolen);

return out2;

} else {

return out;

}

}

private byte[] bits2octets(byte[] in)

{

BigInteger z1 = bits2int(in);

BigInteger z2 = z1.subtract(q);

return int2octets(z2.signum() < 0 ? z1 : z2);

}

/**

Pornin Informational [Page 73]

RFC 6979 Deterministic DSA and ECDSA August 2013

* Set (or reset) the secret key used for HMAC.

*

* @param K the new secret key

*/

private void setHmacKey(byte[] K)

{

try {

hmac.init(new SecretKeySpec(K, macName));

} catch (InvalidKeyException ike) {

throw new IllegalArgumentException(ike);

}

}

/**

* Compute the pseudorandom k for signature generation,

* using the process specified for deterministic DSA.

*

* @param h1 the hashed message

* @return the pseudorandom k to use

*/

private BigInteger computek(byte[] h1)

{

/*

* Convert hash value into an appropriately truncated

* and/or expanded sequence of octets. The private

* key was already processed (into field bx[]).

*/

byte[] bh = bits2octets(h1);

/*

* HMAC is always used with K as key.

* Whenever K is updated, we reset the

* current HMAC key.

*/

/* step b. */

byte[] V = new byte[holen];

for (int i = 0; i < holen; i ++) {

V[i] = 0x01;

}

/* step c. */

byte[] K = new byte[holen];

setHmacKey(K);

/* step d. */

hmac.update(V);

hmac.update((byte)0x00);

Pornin Informational [Page 74]

RFC 6979 Deterministic DSA and ECDSA August 2013

hmac.update(bx);

hmac.update(bh);

K = hmac.doFinal();

setHmacKey(K);

/* step e. */

hmac.update(V);

V = hmac.doFinal();

/* step f. */

hmac.update(V);

hmac.update((byte)0x01);

hmac.update(bx);

hmac.update(bh);

K = hmac.doFinal();

setHmacKey(K);

/* step g. */

hmac.update(V);

V = hmac.doFinal();

/* step h. */

byte[] T = new byte[rolen];

for (;;) {

/*

* We want qlen bits, but we support only

* hash functions with an output length

* multiple of 8;acd hence, we will gather

* rlen bits, i.e., rolen octets.

*/

int toff = 0;

while (toff < rolen) {

hmac.update(V);

V = hmac.doFinal();

int cc = Math.min(V.length,

T.length - toff);

System.arraycopy(V, 0, T, toff, cc);

toff += cc;

}

BigInteger k = bits2int(T);

if (k.signum() > 0 && k.compareTo(q) < 0) {

return k;

}

/*

* k is not in the proper range; update

* K and V, and loop.

*/

Pornin Informational [Page 75]

RFC 6979 Deterministic DSA and ECDSA August 2013

hmac.update(V);

hmac.update((byte)0x00);

K = hmac.doFinal();

setHmacKey(K);

hmac.update(V);

V = hmac.doFinal();

}

}

/**

* Process one more byte of input data (message to sign).

*

* @param in the extra input byte

*/

public void update(byte in)

{

dig.update(in);

}

/**

* Process some extra bytes of input data (message to sign).

*

* @param in the extra input bytes

*/

public void update(byte[] in)

{

dig.update(in, 0, in.length);

}

/**

* Process some extra bytes of input data (message to sign).

*

* @param in the extra input buffer

* @param off the extra input offset

* @param len the extra input length (in bytes)

*/

public void update(byte[] in, int off, int len)

{

dig.update(in, off, len);

}

/**

* Produce the signature. {@link #setPrivateKey} MUST have

* been called. The signature is computed over the data

* that was input through the {@code update*()} methods.

* This engine is then reset (made ready for a new

* signature generation).

*

Pornin Informational [Page 76]

RFC 6979 Deterministic DSA and ECDSA August 2013

* @return the signature

*/

public byte[] sign()

{

return signHash(dig.digest());

}

/**

* Produce the signature. {@link #setPrivateKey} MUST

* have been called. The signature is computed over the

* provided hash value (data is assumed to have been hashed

* externally). The data that was input through the

* {@code update*()} methods is ignored, but kept.

*

* If the hash output is longer than the subgroup order

* (the length of q, in bits, denoted 'qlen'), then the

* provided value {@code h1} can be truncated, provided that

* at least qlen leading bits are preserved. In other words,

* bit values in {@code h1} beyond the first qlen bits are

* ignored.

*

* @param h1 the hash value

* @return the signature

*/

public byte[] signHash(byte[] h1)

{

if (p == null) {

throw new IllegalStateException(

"no private key set");

}

try {

BigInteger k = computek(h1);

BigInteger r = g.modPow(k, p).mod(q);

BigInteger s = k.modInverse(q).multiply(

bits2int(h1).add(x.multiply(r)))

.mod(q);

/*

* Signature encoding: ASN.1 SEQUENCE of

* two INTEGERs. The conditions on q

* imply that the encoded version of r and

* s is no longer than 127 bytes for each,

* including DER tag and length.

*/

byte[] br = r.toByteArray();

byte[] bs = s.toByteArray();

int ulen = br.length + bs.length + 4;

int slen = ulen + (ulen >= 128 ? 3 : 2);

Pornin Informational [Page 77]

RFC 6979 Deterministic DSA and ECDSA August 2013

byte[] sig = new byte[slen];

int i = 0;

sig[i ++] = 0x30;

if (ulen >= 128) {

sig[i ++] = (byte)0x81;

sig[i ++] = (byte)ulen;

} else {

sig[i ++] = (byte)ulen;

}

sig[i ++] = 0x02;

sig[i ++] = (byte)br.length;

System.arraycopy(br, 0, sig, i, br.length);

i += br.length;

sig[i ++] = 0x02;

sig[i ++] = (byte)bs.length;

System.arraycopy(bs, 0, sig, i, bs.length);

return sig;

} catch (ArithmeticException ae) {

throw new IllegalArgumentException(

"DSA error (bad key ?)", ae);

}

}

/**

* Reset this engine. Data input through the {@code

* update*()} methods is discarded. The current private key,

* if one was set, is kept unchanged.

*/

public void reset()

{

dig.reset();

}

}

// ==================================================================

Pornin Informational [Page 78]

RFC 6979 Deterministic DSA and ECDSA August 2013

Author's Address

Thomas Pornin

Quebec, QC

Canada

EMail: pornin@bolet.org