• Stars
    star
    122
  • Rank 292,031 (Top 6 %)
  • Language
    Objective-C
  • License
    BSD 2-Clause "Sim...
  • Created over 10 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Elliptic Curve Cryptography library for iOS (ECDSA and ECDH)

Elliptic Curve Crypto

An Objective-C library for Elliptic Curve Digital Signing Algorithm (ECDSA) and for Elliptic Curve Diffie-Hellman (ECDH).

ECDSA allows signatures to be generated using a private key and validated using a public key.

ECDH allows two identities to use their own private keys and each other's public key to generate a shared secret, which can then be used for encryption.

This library is largely based on the easy-ecc library (https://github.com/kmackay/easy-ecc).

Features

  • Supports: secp128r1, secp192r1, secp256r1, secp384r1
  • Automatically detects curve based on private or public key
  • Supports keys as raw bytes or as base64 encoded strings
  • BSD 2-clause license

API

Generate a new ECC key pair

GMEllipticCurveCrypto *crypto = [GMEllipticCurveCrypto generateKeyPairForCurve:
                                                         GMEllipticCurveSecp192r1];
NSLog(@"Public Key: %@", crypto.publicKeyBase64);
NSLog(@"Private Key: %@", crypto.privateKeyBase64);

Using keys

Keys can be accessed and set interchangably in either raw bytes or as base64 encoded strings.

crypto.publicKeyBase64 = @"AtF8hCxh9h1zlExuOZutuw+tRzmk3zVdfA==";
NSLog(@"Public Key: base64=%@, rawBinary=%@", crypto.publicKeyBase64, crypto.publicKey);

char bytes[] = { 2, 209, 124, 132, 44, 97, 246, 29, 115, 148, 76, 110, 57, 155, 173, 
                 187, 15, 173, 71, 57, 164, 223, 53, 93, 124 };
crypto.publicKey = [NSData dataWithBytes:bytes length:25];
NSLog(@"Public Key: base64=%@, rawBinary=%@", crypto.publicKeyBase64, crypto.publicKey);

Generate a signature for a message

The signing operations require a message the same length as the curve; so generally, a hash algorithm is used to fix the original message's length.

Signatures using ECDSA will be twice the curve size. So, the 192 bit curve will produce a signature that is 48 bytes (384 bits) long.

Also note that the signature is intentionally different each time because ECDSA uses a random k value.

// The first 24 bytes of the SHA-256 hash for "Hack the Planet!"
char bytes[] = { 56, 164, 34, 250, 121, 21, 2, 18, 65, 4, 161, 90, 126, 145, 111, 204, 
                 151, 65, 181, 4, 231, 177, 117, 154 };
NSData *messageHash = [NSData dataWithBytes:bytes length:24];
        
GMEllipticCurveCrypto *crypto = [GMEllipticCurveCrypto cryptoForCurve:
                                                GMEllipticCurveSecp192r1];
crypto.privateKeyBase64 = @"ENxb+5pCLAGT88vGmE6XLQRH1e8i/0rz";
NSData *signature = [crypto signatureForHash:messageHash];
NSLog(@"Signature: %@", signature);

Verify a signature

// messageHash and signature from above

crypto = [GMEllipticCurveCrypto cryptoForCurve:GMEllipticCurveSecp192r1];
crypto.publicKeyBase64 = @"AtF8hCxh9h1zlExuOZutuw+tRzmk3zVdfA==";;
BOOL valid = [crypto verifySignature:signature forHash:messageHash];
NSLog(@"Valid Signature: %@", (valid ? @"YES": @"NO"));

Shared secret

Shared secrets using ECDH are the same length as the curve. So, the 192 bit curve will produce a shared secret that is 24 bytes (192 bits) long.

NSString *alicePublicKey = @"A9N+XWIjLCYAwa8Hb7T6Rohttqo91CF8HQ==";
NSString *alicePrivateKey = @"frs4puAKipcbevvwJb7l77xACgB/FyBv";

NSString *bobPublicKey = @"A35aoteno4wnAdJgV8AXKKl1AfPVRrSZQA==";
NSString *bobPrivateKey = @"LP83qv81MsXVyPOFV7V5jKVOoU4DKPUS";


// Alice performs...
GMEllipticCurveCrypto *alice = [GMEllipticCurveCrypto cryptoForCurve:
                                               GMEllipticCurveSecp192r1];
alice.privateKeyBase64 = alicePrivateKey;
NSData *aliceSharedSecret = [alice sharedSecretForPublicKeyBase64:bobPublicKey];
NSLog(@"Shared Secret Alice: %@", aliceSharedSecret);

// Bob performs...
GMEllipticCurveCrypto *bob = [GMEllipticCurveCrypto cryptoForCurve:
                                             GMEllipticCurveSecp192r1];
bob.privateKeyBase64 = bobPrivateKey;
NSData *bobSharedSecret = [bob sharedSecretForPublicKeyBase64:alicePublicKey];
NSLog(@"Shared Secret Bob: %@", bobSharedSecret);

// And now both parties have the same secret!
NSLog(@"Shared secrets equal? %d", [aliceSharedSecret isEqualToData:bobSharedSecret]);

Convenience functions

Automatically detects curve and sets up the private or public key

+ (GMEllipticCurveCrypto*)cryptoForKey: (NSData*)privateOrPublicKey;
+ (GMEllipticCurveCrypto*)cryptoForKeyBase64: (NSString*)privateOrPublicKey;

Automatically hash and compute the signature for a message

Include the GMEllipticCurveCrypto+hash.h category to hash data automatically before signing and verifying. The hash algorithm used must be at least the length of the curve. The hash will have the right-most bytes truncated, if necessary.

- (NSData*)hashSHA256AndSignData: (NSData*)data;
- (BOOL)hashSHA256AndVerifySignature: (NSData*)signature forData: (NSData*)data;

- (NSData*)hashSHA384AndSignData: (NSData*)data;
- (BOOL)hashSHA384AndVerifySignature: (NSData*)signature forData: (NSData*)data;

Why?

Kenneth MacKay's easy-ecc is an awesome, simple-to-use implementation of essential Elliptic Curve Cryptographic functions, however, the curve used is specified as a compile-time constant, so it cannot be changed at runtime.

This library allows any and as many different curves to be used at once.

Donations?

Sure! :-)

Bitcoin - 1LNdGsYtZXWeiKjGba7T997qvzrWqLXLma

More Repositories

1

aes-js

A pure JavaScript implementation of the AES block cipher and all common modes of operation for node.js or web browsers.
JavaScript
1,451
star
2

QRCode

QR code generation library in C, optimized for low-power devices, such as Arduino.
C++
649
star
3

pyaes

Pure-Python implementation of AES block-cipher and common modes of operation.
Python
456
star
4

nightminer

Simple Python CryptoCurrency mining client
Python
198
star
5

scrypt-js

Pure JavaScript implementation of the scrypt password-based key derivation function.
JavaScript
141
star
6

pycoind

Pure-Python full node and libraries for bitcoind-based crypto-currencies (eg. bitcoin, litecoin, etc)
Python
121
star
7

ethers-airdrop

A simple tool and library to deploy and manage a Merkle Air-Drop.
JavaScript
93
star
8

lurch

Lurch is an Ethereum VM para-virtualization (ish) written in EVM bytecode.
Assembly
83
star
9

pyscrypt

Pure-Python implementation of Scrypt PBKDF and scrypt file format library.
Python
82
star
10

ethers-meow

A simple command-line interface and library for CryptoKitties using ethers.js.
JavaScript
73
star
11

Takoyaki

ENS the fun and easy way; like a box of cereal, there is a toy at the bottom.
TypeScript
37
star
12

will-o-the-wisp

Intentionally self-destructive Ethereal on-chain-ish Wallet. (Proof-of-Concept bootstrap technique with CREATE2)
JavaScript
35
star
13

meeseeks-app

Safely load verified IPFS content on its own domain with browser Cross-Origin Policy protection.
HTML
28
star
14

multicall

A simple multicall contract and library wrapper to aggregate Ethereum calls.
TypeScript
24
star
15

flatworm

A very simple documentation generation tool.
JavaScript
18
star
16

gas-ticker

Oracle for tracking effective gas prices.
JavaScript
17
star
17

gremlins

A simple and easy-to-use language and compiler for querying blockchain data.
TypeScript
11
star
18

account-scanner

A simple example of a multi-call contract for token scanning.
JavaScript
11
star
19

BLECast

A custom protocol and library for iOS to send messages to Arduino over BLE advertising data.
C
10
star
20

sprinkles

NFTHack 2021 project: Sprinkles
C
8
star
21

GMClipper

An Objective-C wrapper for the Clipper polygon clipping and offsetting library.
C++
7
star
22

distinguished-format-strings

Deprecated. This idea has been obsoleted in favour of described data (see link).
JavaScript
5
star
23

waxlit

The WaxLit experimental blogging libraries and front-end
HTML
5
star
24

ethers-studio

Initial experimental project for Ethers Studio.
TypeScript
5
star
25

reticulate

Package manger for the ethers monorepo and ancillary packages.
TypeScript
4
star
26

coindjs

JavaScript implementation of Bitcoin (Namecoin, etc) full node and libraries for node.js.
JavaScript
4
star
27

vanity-contract

Miner for generating Vanity Contract Addresses.
C
3
star
28

hatch

Hatches ENS-controlled long-lived Wisp-like Proxies.
Solidity
3
star
29

ethdenver2024

ETHDenver 2024 Hackathon Project
1
star
30

promise-rationing

Promise-like interface to limit how many concurrent promises are executed.
JavaScript
1
star
31

sandbox

Random little things here and there, that I don't know where else to put.
JavaScript
1
star
32

USCC-2017

My entry for the Under-Handed Solidity Coding Competition 2017 (2nd place)
JavaScript
1
star