Author Topic: can we save memo's one time key for two copy?  (Read 1488 times)

0 Members and 1 Guest are viewing this topic.

Offline xeroc

  • Board Moderator
  • Hero Member
  • *****
  • Posts: 12922
  • ChainSquad GmbH
    • View Profile
    • ChainSquad GmbH
  • BitShares: xeroc
  • GitHub: xeroc
@Elmato, I agree .. However, I already started to rewrite my library .. in particular the Address, Base58 and BIP38 modules ... I will push what I have into a repo and can add your github handles there if you wish

https://github.com/BitSharesEurope/python-bitshareslib
« Last Edit: May 30, 2015, 10:17:28 am by xeroc ¯\_(ツ)_/¯ »

Offline ElMato

  • Sr. Member
  • ****
  • Posts: 288
    • View Profile
@alt, what we are doing (kind of hacky but we have plan-b)

We are using the slate field of the deposit operation (since we are moving BTA only not BTS and BTA balances votes dont count ) to store the derivation index of an HDKey that was used to create the shared secret.

Plan-B would be to use the op_data operation in case we have problems in the future (node rejecting an operation of BTA with slate != 0).

@xeroc and @alt, we should combine our efforts on the python library, i think we all three have write the same code.
(order book processing [bids+asks+shorts], address/pubkey creation/decoding, etc).

Here is some ugly code for memo creation/decoding.
The bitcoin library is https://github.com/vbuterin/pybitcointools

Code: [Select]
#!/usr/bin/python
import sys,os
sys.path[0:0] =  [os.path.join(os.path.dirname(os.path.abspath(__file__)), '../lib')]

from hashlib import sha512
import bitcoin as b
from helper import *

if len(sys.argv) < 4:
  print 'memo_enc.py message from_pub to_pub'
  sys.exit(0)

_message  = sys.argv[1]
_from_pub = sys.argv[2]
_to_pub   = sys.argv[3]

def compute_encrypted_memo(message, from_pub, to_pub):

  print 'Compute encrypted memo'
  print message
  print from_pub
  print to_pub
  print hack_info

  # Compute shared secret
  def compute_shared_secret(pub, priv):
    Xk = b.encode_pubkey(b.multiply(pub, priv), 'hex_compressed')[2:]
    return sha512(Xk.decode('hex')).digest()

  #TODO: remove
  priv_key = b.random_key()

  ss = compute_shared_secret(decode_pub(to_pub), priv_key)

  fpub = decode_pub(from_pub).decode('hex')

  if len(message) < 19:
    message = message + chr(0)*(19-len(message))

  message = message[:51]

  memo_data = fpub + chr(0)*8 + message[:19] + '\0'
  if len(message) > 19:
    memo_data += message[19:19+32]

  print 'voy aca'

  length = 16 - (len(memo_data) % 16)
  memo_data += chr(length)*length

  from Crypto.Cipher import AES
  obj = AES.new(ss[0:32], AES.MODE_CBC, ss[32:48])
  cipher = obj.encrypt(memo_data)

  res = {
    'shared_secret'       : ss.encode('hex'),
    'memo_data'           : memo_data.encode('hex'),
    'one_time_key'        : encode_pub(b.encode_pubkey(b.privtopub(priv_key),'hex_compressed')),
    'encrypted_memo_data' : cipher.encode('hex')
  }

  return res

#res = compute_encrypted_memo(_message, _from_pub, _to_pub)
#import simplejson as json
#print json.dumps(res)

Code: [Select]
#!/usr/bin/python
import sys,os
sys.path[0:0] =  [os.path.join(os.path.dirname(os.path.abspath(__file__)), '../lib')]

from hashlib import sha512
import bitcoin as b
from helper import *

if len(sys.argv) < 4:
  print 'memo_dec.py one_time_key encripted_memo_data priv_key'
  sys.exit(0)

one_time_key        = sys.argv[1]
encripted_memo_data = sys.argv[2]
priv_key            = sys.argv[3]

# Compute shared secret
def compute_shared_secret(pub, priv):
  Xk = b.encode_pubkey(b.multiply(pub, priv), 'hex_compressed')[2:]
  return sha512(Xk.decode('hex')).digest()

ss = compute_shared_secret(decode_pub(one_time_key), priv_key)

from Crypto.Cipher import AES
obj = AES.new(ss[0:32], AES.MODE_CBC, ss[32:48])
plain = obj.decrypt(encripted_memo_data.decode('hex'))

inx=0
def extract(_len):
  global inx
  tmp = plain[inx:inx+_len]
  inx += _len
  return tmp

_from     = plain[inx:inx+33]; inx+=33
_from_sig = plain[inx:inx+8];  inx+=8
_message  = plain[inx:inx+19]; inx+=19
_type     = plain[inx:inx+1];  inx+=1

if len(plain) > 33+8+19+1:
  _message = _message + plain[inx:inx+32]

import string
_message = filter(lambda x: x in string.printable, _message)

res = {
  'shared_secret' : ss.encode('hex'),
  'memo_data'     : plain.encode('hex'),
  'from'          : encode_pub(_from.encode('hex')),
  'from_sig'      : _from_sig.encode('hex'),
  'message'       : _message,
  'type'          : _type.encode('hex')
}

import simplejson as json
print json.dumps(res)

Some helper code

Code: [Select]
import bitcoin as b
import base64
from config import *
import binascii

PROD_PREFIX = 'BTS'
DEV_PREFIX  = 'DVS'

prefix = DEV_PREFIX if is_test() else PROD_PREFIX

def is_valid_address(addy):
  try:
    address_to_hash(addy)
    return True
  except:
    return False

def is_valid_pubkey(pubkey):
  try:
    decode_pub(pubkey)
    return True
  except:
    return False

def address_to_hash(addy):
  assert(addy[0:3] == prefix), 'Invalid prefix'
  data = b.changebase(addy[3:], 58, 256)
  assert(len(data) == 24), 'Invalid length'
  hval = data[:-4]
  assert(data[-4:] == b.ripemd.new(hval).digest()[:4]), 'Invalid checksum'
  return hval.encode('hex')

def pub_to_address(pub):
  r = b.ripemd.new(b.hashlib.sha512(pub.decode('hex')).digest()).digest()
  c = b.ripemd.new(r).digest()
  return prefix+b.changebase(r+c[0:4], 256, 58)

def decode_pub(epub):
  print 'EPUB %s'%epub
  assert(epub[0:3] == prefix), 'Invalid prefix'
  data = b.changebase(epub[3:], 58, 256)
  assert(len(data) == 37), 'Invalid length'
  hval = data[:-4]
  assert(data[-4:] == b.ripemd.new(hval).digest()[:4]), 'Invalid checksum'
  return hval.encode('hex')

def encode_pub(hexpub):
  h = binascii.unhexlify(hexpub)
  return prefix + b.changebase(h + b.ripemd.new(h).digest()[0:4], 256, 58)

def recover_pubkey(msghash, signature):
  sig = base64.b64encode(signature.decode('hex'))
  return encode_pub(b.encode_pubkey(b.ecdsa_raw_recover(msghash,b.decode_sig(sig)),'hex_compressed'))


 

Offline xeroc

  • Board Moderator
  • Hero Member
  • *****
  • Posts: 12922
  • ChainSquad GmbH
    • View Profile
    • ChainSquad GmbH
  • BitShares: xeroc
  • GitHub: xeroc

Offline alt

  • Hero Member
  • *****
  • Posts: 2821
    • View Profile
  • BitShares: baozi
IIRC Elmato put an idea for this somewhere in the forum and one of the devs mentioned that something similar might come eventually
so maybe we can fix this in the next release?

Offline xeroc

  • Board Moderator
  • Hero Member
  • *****
  • Posts: 12922
  • ChainSquad GmbH
    • View Profile
    • ChainSquad GmbH
  • BitShares: xeroc
  • GitHub: xeroc
IIRC Elmato put an idea for this somewhere in the forum and one of the devs mentioned that something similar might come eventually

Offline alt

  • Hero Member
  • *****
  • Posts: 2821
    • View Profile
  • BitShares: baozi
one key can decrypt by receiver's private key.
and one key can decrypt by sender's private key.
then the sender can get the correct memo and receiver from different wallet.