//
//  RCTKcdsa.h
//
//  TaeHeun Lee (nixstory@gmail.com)

#import "RCTKcdsa.h"
#import "./lib/CommonUtil.h"
#import "./lib/kcdsa.h"

@implementation RCTKcdsa

KISA_KCDSA *kcdsa = NULL;

int plen = 2048, qlen = 224;
unsigned char msg[] = { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x4b, 0x43, 0x44, 0x53, 0x41, 0x20, 0x75, 0x73, 0x61, 0x67, 0x65, 0x21 };
unsigned char pbSrc[] = { 0x73, 0x61, 0x6c, 0x64, 0x6a, 0x66, 0x61, 0x77, 0x70, 0x33, 0x39, 0x39, 0x75, 0x33, 0x37, 0x34, 0x72, 0x30, 0x39, 0x38, 0x75, 0x39, 0x38, 0x5e, 0x25, 0x5e, 0x25, 0x68, 0x6b, 0x72, 0x67, 0x6e, 0x3b, 0x6c, 0x77, 0x6b, 0x72, 0x70, 0x34, 0x37, 0x74, 0x39, 0x33, 0x63, 0x25, 0x24, 0x38, 0x39, 0x34, 0x33, 0x39, 0x38, 0x35, 0x39, 0x6b, 0x6a, 0x64, 0x6d, 0x6e, 0x76, 0x63, 0x6d, 0x20, 0x63, 0x76, 0x6b, 0x20, 0x6f, 0x34, 0x75, 0x30, 0x39, 0x72, 0x20, 0x34, 0x6a, 0x20, 0x6f, 0x6a, 0x32, 0x6f, 0x75, 0x74, 0x32, 0x30, 0x39, 0x78, 0x66, 0x71, 0x77, 0x3b, 0x6c, 0x2a, 0x26, 0x21, 0x5e, 0x23, 0x40, 0x55, 0x23, 0x2a, 0x23, 0x24, 0x29, 0x28, 0x23, 0x20, 0x7a, 0x20, 0x78, 0x6f, 0x39, 0x35, 0x37, 0x74, 0x63, 0x2d, 0x39, 0x35, 0x20, 0x35, 0x20, 0x76, 0x35, 0x6f, 0x69, 0x75, 0x76, 0x39, 0x38, 0x37, 0x36, 0x20, 0x36, 0x20, 0x76, 0x6a, 0x20, 0x6f, 0x35, 0x69, 0x75, 0x76, 0x2d, 0x30, 0x35, 0x33, 0x2c, 0x6d, 0x63, 0x76, 0x6c, 0x72, 0x6b, 0x66, 0x77, 0x6f, 0x72, 0x65, 0x74 };
unsigned char kInput[] = { 0x1b, 0xf1, 0x23, 0xb0, 0x27, 0x52, 0xe2, 0xc9, 0xed, 0x81, 0x51, 0x74, 0x69, 0xf2, 0x0b, 0x0c, 0x19, 0xa9, 0x97, 0xa4 };
unsigned char sig[56];
unsigned int siglen;

RCT_EXPORT_MODULE()
    
RCT_EXPORT_METHOD(_KISA_KCDSA_GenerateKeyPair:(NSInteger)hash
                  resolver:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject) {
    
    KISA_KCDSA_CreateObject(&kcdsa);
    KISA_KCDSA_GenerateParameters(plen, qlen, kcdsa, hash);

    // KCDSA 알고리즘의 키 쌍(개인키, 공개키) 생성 함수
    // hash (1:SHA_224, 2:SHA_256)
    
    unsigned int ret = KISA_KCDSA_GenerateKeyPair(kcdsa, pbSrc, 160, qlen, (unsigned int)hash);
    
    //  - 0 : 파라미터 생성 성공
    //  - 2 : 치명적인 오류 발생
    //  - 3 : 유효하지 않은 KCDSA 객체 포인터 입력
    NSString *data = [NSString stringWithFormat:@"%d", ret];

    resolve(data);
}

RCT_EXPORT_METHOD(_KISA_KCDSA_sign:(NSString *)msg hash:(NSInteger)hash
                  resolver:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject) {
    // KCDSA 알고리즘 전자서명 생성 함수
    // hash (1:SHA_224, 2:SHA_256)
    
    NSError *error = nil;

    NSData *n_msg = [msg dataUsingEncoding:NSUTF8StringEncoding];
    NSInteger msg_length = n_msg.length;
    
    KISA_KCDSA_sign(kcdsa, n_msg, msg_length, sig, &siglen, hash, kInput, 20);
    if (sig == nil) {
        reject(@"sign_fail", @"Sign failed", error);
    } else {
        // 전자서명값
        NSString *data = [NSString stringWithFormat:@"%@", [CommonUtil toHex:sig]];

        resolve(data);
    }
}

RCT_EXPORT_METHOD(_KISA_KCDSA_verify:(NSString *)msg sign:(NSString *)sign hash:(NSInteger)hash
                  resolver:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject) {
    // KCDSA 알고리즘 전자서명 검증 함수
    // hash (1:SHA_224, 2:SHA_256)

    NSError *error = nil;

    NSData *n_msg = [msg dataUsingEncoding:NSUTF8StringEncoding];
    NSInteger msg_length = n_msg.length;
    
    NSData *n_sign = [sign dataUsingEncoding:NSUTF8StringEncoding];
    NSInteger sign_length = n_sign.length;

    unsigned int ret = KISA_KCDSA_verify(kcdsa, n_msg, msg_length, n_sign, sign_length, hash);
    
    //  - 0 : 전자서명 검증 성공
    //  - 1 : 전자서명 검증 실패
    //  - 2 : 치명적인 오류 발생
    //  - 3 : 유효하지 않은 KCDSA 구조체 포인터 입력
    //  - 4 : 유효하지 않은 알고리즘 파라미터 입력
    NSString *data = [NSString stringWithFormat:@"%d", ret];
    
    resolve(data);
}

@end
