Digital signatures depend upon message and the secret key. Suppose receiver copies the message several times ( the reason for which we unique ids) , why will the signature be different (since the message and secret key are same)?
Digital signatures depend upon message and the secret key. Suppose receiver copies the message several times ( the reason for which we unique ids) , why will the signature be different (since the message and secret key are same)?
Bitcoin uses ECDSA, and the reason the signature is different for the same message and key is the random nonce, which is generated each time a signature is created.
An ECDSA signature is a pair (r,s) where r is the X coordinate of kG, and s = (m+r*x)/k (where k=nonce, m=message hash, x=private key, G=curve generator).
See also #3 in https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Signature_generation_algorithm
This answer is just a practical supplement to the theoretical answer provided above. This snippet digitally signs inside the for-loop the same message over and over again using the same private key and each time, it is printing out different digital signatures. Each of these signatures are valid and will verify using the signer's public key.
import java.security.Security;
import java.security.Signature;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.SecureRandom;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.interfaces.ECPublicKey;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
class liptic
{
static String the_message = "how are you, little tiger?";
public static void main(String args[]) throws Exception
{
Security.addProvider(new BouncyCastleProvider());
SecureRandom random = new SecureRandom();
ECParameterSpec ecSpec
=
ECNamedCurveTable.getParameterSpec("secp256k1");
KeyPairGenerator g =
KeyPairGenerator.getInstance("ECDH", "BC");
g.initialize(ecSpec, random);
KeyPair keyPair = g.generateKeyPair();
byte[] bob_pubkey = Hex.decode( "040581E4AEEEB1CEA57094D1AD97B8C721509B6E5D3690C70BBB8EB2C5FE8040"
+ "FB2C9B0A77EA2AD05C5E8DB499F647BC9A8BE829961950D6F5A45952C097CCB0BC");
Signature signer = Signature.getInstance("SHA256withECDSA", "BC");
ECPublicKeySpec pubkSpec = new ECPublicKeySpec(
ecSpec.getCurve().decodePoint(bob_pubkey), ecSpec);
ECPublicKey publicKey
= (ECPublicKey)KeyFactory.getInstance("ECDSA", "BC")
.generatePublic(pubkSpec);
byte[] signature = null;
byte[] input = the_message.getBytes();
signer.initSign(keyPair.getPrivate());
signer.update(input);
for (int i = 0; i < 5; i++) {
signature = signer.sign();
System.out.println(o(signature));
}
}
public static String o(byte[] bytes)
{
int n = 0;
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02X", b));
n++;
if (n % 128 == 0) {
sb.append("\n");
}
}
return sb.toString();
}
}
Here are the digital signatures:
This is using the Elliptic Curve Digital Signature Algorithm.