рдЗрд╕реЗ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдХрд┐рдП рдмрд┐рдирд╛ рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рдЗрд╕реЗ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдХрд┐рдП рдмрд┐рдирд╛ рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛
рдпрд╣ рдЖрд▓реЗрдЦ рдЙрдиреНрдирдд рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлрд╝рд┐рдХ рддрдХрдиреАрдХреЛрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдЬреВрд▓рд┐рдпрд╛ рдХрдореНрдкреНрдпреВрдЯрд┐рдВрдЧ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдП рдЧрдП рд╢реЛрдз рдХрд╛ рд╕рд┐рд░реНрдл рдПрдХ рдЕрд╡рд▓реЛрдХрди рд╣реИред рд╡рд╛рдгрд┐рдЬреНрдпрд┐рдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдпрд╣рд╛рдВ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рди рдХрд░реЗрдВред рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлреА рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣рдореЗрд╢рд╛ рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлрд░реНрд╕ рдХреЗ рд╕рд╛рде рдкрд░рд╛рдорд░реНрд╢ рдХрд░реЗрдВред

рдпрд╣рд╛рдВ рдЖрдк рдЙрд╕ рдкреИрдХреЗрдЬ рдХреЛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╕рднреА рдЬрд╛рджреВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рд▓реЗрдЦ рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдЧрдИ рдХреЛрдб рд╣реИред

рдкрд░рд┐рдЪрдп


рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдкрдиреЗ рдЕрднреА-рдЕрднреА рдПрдХ рдХреВрд▓ рдирдИ рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧ рдореЙрдбрд▓ (рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдлреНрд▓рдХреНрд╕.рдЬреЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ ) рд╡рд┐рдХрд╕рд┐рдд рдХреА рд╣реИ ред рдФрд░ рдЕрдм рдЖрдк рдЗрд╕реЗ рдЕрдкрдиреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рддреИрдирд╛рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдЖрдк рдпрд╣ рдХреИрд╕реЗ рдХрд░реЗрдВрдЧреЗ? рд╕рдВрднрд╡рдд: рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдореЙрдбрд▓ рджреЗрдирд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рдЕрдкрдиреЗ рдбреЗрдЯрд╛ рдкрд░ рд╕реНрдерд╛рдиреАрдп рд░реВрдк рд╕реЗ рдЪрд▓рд╛рдиреЗ рджреЗрдирд╛ рд╣реИред рд▓реЗрдХрд┐рди рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдиреБрдХрд╕рд╛рди рд╣реИрдВ:

  1. рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧ рдореЙрдбрд▓ рдмрдбрд╝реЗ рд╣реИрдВ, рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрдВрдкреНрдпреВрдЯрд░ рдореЗрдВ рдкрд░реНрдпрд╛рдкреНрдд рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдпрд╛ рдбрд┐рд╕реНрдХ рд╕рдВрд╕рд╛рдзрди рдирд╣реАрдВ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
  2. рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧ рдореЙрдбрд▓ рдЕрдХреНрд╕рд░ рдЕрдкрдбреЗрдЯ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдпрд╣ рдЖрдкрдХреЗ рд▓рд┐рдП рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рдирд┐рдпрдорд┐рдд рд░реВрдк рд╕реЗ рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдбреЗрдЯрд╛ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
  3. рдореЙрдбрд▓ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдореЗрдВ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдФрд░ рдЖрдк рдЕрдкрдиреЗ рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реБрд▓реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдореБрдЖрд╡рдЬрд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рддрдм рд╡реЗ рдЖрдорддреМрд░ рдкрд░ рдпрд╛рдж рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдореЙрдбрд▓ рдХреЛ рдПрдкреАрдЖрдИ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреНрд▓рд╛рдЙрдб рдореЗрдВ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдкрд┐рдЫрд▓реЗ рдХреБрдЫ рд╡рд░реНрд╖реЛрдВ рдореЗрдВ, рдРрд╕реА рдХрдИ рд╕реЗрд╡рд╛рдПрдБ рд╕рд╛рдордиреЗ рдЖрдИ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рдмрдбрд╝рд╛ рдХреНрд▓рд╛рдЙрдб рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдХреЙрд░реНрдкреЛрд░реЗрдЯ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рд╕рдорд╛рди рд╕реЗрд╡рд╛рдПрдБ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╕рдВрднрд╛рд╡рд┐рдд рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдПрдХ рд╕реНрдкрд╖реНрдЯ рджреБрд╡рд┐рдзрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рдирд╛ рдкрдбрд╝рддрд╛ рд╣реИ: рдЕрдм рдЙрдирдХрд╛ рдбреЗрдЯрд╛ рдПрдХ рджреВрд░рд╕реНрде рд╕рд░реНрд╡рд░ рдкрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рднрд░реЛрд╕реЗрдордВрдж рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд╕реНрдкрд╖реНрдЯ рдиреИрддрд┐рдХ рдФрд░ рдХрд╛рдиреВрдиреА рдирд┐рд╣рд┐рддрд╛рд░реНрде рд╣реИрдВ рдЬреЛ рдРрд╕реА рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рд╕реАрдорд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╡рд┐рдирд┐рдпрдорд┐рдд рдЙрджреНрдпреЛрдЧреЛрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕реНрд╡рд╛рд╕реНрдереНрдп рджреЗрдЦрднрд╛рд▓ рдФрд░ рд╡рд┐рддреНрддреАрдп рд╕реЗрд╡рд╛рдУрдВ рдореЗрдВ, рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЛ рд░реЛрдЧреА рдФрд░ рдЧреНрд░рд╛рд╣рдХ рдбреЗрдЯрд╛ рднреЗрдЬрдирд╛ рдЕрдХреНрд╕рд░ рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рдХреЛрдИ рдЕрдиреНрдп рд╡рд┐рдХрд▓реНрдк?

рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ рд╡рд╣рд╛рдБ рд╣реИ! рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлреА рдореЗрдВ рд╣рд╛рд▓ рдХреА рдЦреЛрдЬреЛрдВ рдиреЗ рдЗрд╕реЗ рдбрд┐рдХреЛрдб рдХрд┐рдП рдмрд┐рдирд╛ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ рдХреА рдЕрдиреБрдорддрд┐ рджреА рд╣реИ ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдХ рдХреНрд▓рд╛рдЙрдб рдПрдкреАрдЖрдИ рдХреЗ рд▓рд┐рдП рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдбреЗрдЯрд╛ (рдХрд╣рддреЗ рд╣реИрдВ, рдЫрд╡рд┐рдпрд╛рдВ) рднреЗрдЬрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧ рдореЙрдбрд▓ рд▓реЙрдиреНрдЪ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдПрдХ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рднреЗрдЬрддрд╛ рд╣реИред рдХрд┐рд╕реА рднреА рд╕реНрддрд░ рдкрд░ рдбреЗрдЯрд╛ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдХреНрд▓рд╛рдЙрдб рдкреНрд░рджрд╛рддрд╛ рд╕реНрд░реЛрдд рдЫрд╡рд┐рдпреЛрдВ рддрдХ рдкрд╣реБрдВрдЪ рдкреНрд░рд╛рдкреНрдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЧрдгрдирд╛ рдХрд┐рдП рдЧрдП рдкреВрд░реНрд╡рд╛рдиреБрдорд╛рди рдХреЛ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдХреИрд╕реЗ рд╕рдВрднрд╡ рд╣реИ? рдЖрдЗрдП MNIST рдбрд╛рдЯрд╛рд╕реЗрдЯ рд╕реЗ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдЫрд╡рд┐рдпреЛрдВ рдкрд░ рд▓рд┐рдЦрд╛рд╡рдЯ рдорд╛рдиреНрдпрддрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реЗрд╡рд╛ рдмрдирд╛рдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░ рдкрддрд╛ рд▓рдЧрд╛рддреЗ рд╣реИрдВред

Homomorphic рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ


рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЛ рдЖрдорддреМрд░ рдкрд░ "рд╕реБрд░рдХреНрд╖рд┐рдд рдХрдВрдкреНрдпреВрдЯрд┐рдВрдЧ" рдХреЗ рд░реВрдк рдореЗрдВ рдЬрд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣ рдЕрдиреБрд╕рдВрдзрд╛рди рдХреЗ рд▓рд┐рдП рдПрдХ рдмрдбрд╝рд╛ рдХреНрд╖реЗрддреНрд░ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлреА рдХреЗ рдХрдИ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣реИрдВред рд╣рдо "рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдХ рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди" рдирд╛рдордХ рддрдХрдиреАрдХ рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░реЗрдВрдЧреЗред рдЗрд╕ рддрд░рд╣ рдХреА рдкреНрд░рдгрд╛рд▓реА рдореЗрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдСрдкрд░реЗрд╢рди рдЖрдорддреМрд░ рдкрд░ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реИрдВ:

  • pub_key, eval_key, priv_key = keygen()
  • encrypted = encrypt(pub_key, plaintext)
  • decrypted = decrypt(priv_key, encrypted)
  • encryptedтА▓ = eval(eval_key, f, encrypted)

рдкрд╣рд▓реЗ рддреАрди рдСрдкрд░реЗрд╢рди рд╕рд░рд▓ рдФрд░ рд╕рднреА рдХреЗ рд▓рд┐рдП рдкрд░рд┐рдЪрд┐рдд рд╣реИрдВ рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд┐рд╕реА рднреА рдЕрд╕рдордорд┐рдд рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЖрдк рдЯреАрдПрд▓рдПрд╕ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ)ред рд╕рд╛рд░рд╛ рдЬрд╛рджреВ рдЖрдЦрд┐рд░реА рдСрдкрд░реЗрд╢рди рдореЗрдВ рд╣реЛрддрд╛ рд╣реИред рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдХреЗ рджреМрд░рд╛рди, рдпрд╣ рдлрд╝рдВрдХреНрд╢рди f рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдореВрд▓реНрдп рдкрд░ f рдХреЗ рдореВрд▓реНрдпрд╛рдВрдХрди рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЧрдгрдирд╛ рдХреА рдЧрдИ рдПрдХ рдФрд░ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИред рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдиреЗ рдЕрдкрдиреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЛ рдЕрдкрдирд╛ рдирд╛рдо рджрд┐рдпрд╛ред рдореВрд▓реНрдпрд╛рдВрдХрди рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдСрдкрд░реЗрд╢рди рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рд╣реИ:

 f(decrypt(priv_key, encrypted)) == decrypt(priv_key, eval(eval_key, f, encrypted)) 

рдЗрд╕реА рддрд░рд╣, рдПрдХ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдореВрд▓реНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рд╣рдо рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдЬреНрдо рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдХреМрди рд╕реЗ рдХрд╛рд░реНрдп f рд╕рдорд░реНрдерд┐рдд рд╣реИ рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлрд┐рдХ рдпреЛрдЬрдирд╛рдУрдВ рдФрд░ рд╕рдорд░реНрдерд┐рдд рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдХреЗрд╡рд▓ рдПрдХ f рд╕рдорд░реНрдерди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, f = + ), рддреЛ рд╕рд░реНрдХрд┐рдЯ рдХреЛ "рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдХ" рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрджрд┐ f рдЧреЗрдЯрд╡реЗ рдХрд╛ рдХреЛрдИ рднреА рдкреВрд░рд╛ рд╕реЗрдЯ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдордирдорд╛рдиреА рдпреЛрдЬрдирд╛рдПрдВ рдмрдирд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИрдВ, рддреЛ рдПрдХ рдпреЛрдЬрдирд╛ рдХреЗ рд╕реАрдорд┐рдд рдЖрдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдХ рдЧрдгрдирд╛ рдХрд╛ рдПрдХ рдФрд░ рдкреНрд░рдХрд╛рд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ - "рдХреБрдЫ рд╣рдж рддрдХ рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдХ", рдФрд░ рдЕрд╕реАрдорд┐рдд рдЖрдХрд╛рд░ рдХреЗ рд▓рд┐рдП - "рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдХ" рдЧрдгрдирд╛ред рдЖрдк рдмреВрдЯрд╕реНрдЯреНрд░реИрдкрд┐рдВрдЧ рддрдХрдиреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ "рдХрд┐рд╕реА рддрд░рд╣" рдХреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдХ рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдореЗрдВ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рд╣рдорд╛рд░реЗ рд▓реЗрдЦ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдкрд░реЗ рд╣реИред рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдХ рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдПрдХ рдЕрдкреЗрдХреНрд╖рд╛рдХреГрдд рд╣рд╛рд▓ рд╣реА рдХреА рдЦреЛрдЬ рд╣реИ, рдкрд╣рд▓реА рдХрд╛рд░реНрдп рдпреЛрдЬрдирд╛ (рдпрджреНрдпрдкрд┐ рдЕрд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ) 2009 рдореЗрдВ рдХреНрд░реЗрдЧ рдЬреЗрдВрдЯреНрд░реА рджреНрд╡рд╛рд░рд╛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХреА рдЧрдИ рдереАред рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдХ рдпреЛрдЬрдирд╛рдПрдВ рдмрд╛рдж рдореЗрдВ (рдФрд░ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ) рдХрдИ рд╣реИрдВред рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдкреИрдХреЗрдЬ рднреА рд╣реИрдВ рдЬреЛ рдЗрди рдпреЛрдЬрдирд╛рдУрдВ рдХреЛ рдЧреБрдгрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВред рдЕрдХреНрд╕рд░ рд╡реЗ Microsoft SEAL рдФрд░ PALISADE рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореИрдВрдиреЗ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдЗрди рд╢реБрджреНрдз рдЬреВрд▓рд┐рдпрд╛ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛрдб рдЦреЛрд▓рд╛ рд╣реИред рдЗрд╕ рд▓реЗрдЦ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕рдореЗрдВ рд▓рд╛рдЧреВ CKKS рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

CKS рдЕрд╡рд▓реЛрдХрди


CKKS ( рд╡реИрдЬреНрдЮрд╛рдирд┐рдХ рдХрд╛рд░реНрдп рдЪреЗрдУрди-рдХрд┐рдо-рдХрд┐рдо-рд╕реЛрдВрдЧ рдХреЗ рд▓реЗрдЦрдХреЛрдВ рдХреЗ рдирд╛рдо рд╕реЗ, рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ 2016 рдореЗрдВ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рд░рдЦрд╛ рдерд╛) рдПрдХ рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдХ рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдпреЛрдЬрдирд╛ рд╣реИ рдЬреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЖрджрд┐рдо рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдХ рдореВрд▓реНрдпрд╛рдВрдХрди рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ:

  • рдЬрдЯрд┐рд▓ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ n рд╡реИрдХреНрдЯрд░ рдХреА рд▓рдВрдмрд╛рдИ рдХреЗ рддрддреНрд╡рдкреВрд░реНрдг рдЬреЛрдбрд╝ред
  • n рдХреЙрдореНрдкреНрд▓реЗрдХреНрд╕ рд╡реИрдХреНрдЯрд░ рдХреА рд▓рдВрдмрд╛рдИ рдХрд╛ рддрддреНрд╡рд╡рд╛рд░ рдЧреБрдгрд╛ред
  • рдПрдХ рд╕рджрд┐рд╢ рдореЗрдВ рддрддреНрд╡реЛрдВ ( circshift рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ) рдХреЛ circshift ред
  • рд╡реЗрдХреНрдЯрд░ рддрддреНрд╡реЛрдВ рдХреА рдПрдХреАрдХреГрдд рдЬреЛрдбрд╝реАред

рдкреИрд░рд╛рдореАрдЯрд░ n рд╕реБрд░рдХреНрд╖рд╛ рдФрд░ рд╕рдЯреАрдХрддрд╛ рдХреЗ рд╡рд╛рдВрдЫрд┐рдд рд╕реНрддрд░ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЖрдорддреМрд░ рдкрд░ рдХрд╛рдлреА рдЕрдзрд┐рдХ рд╣реЛрддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдпрд╣ 4096 рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрдЧрд╛ (рдПрдХ рдЙрдЪреНрдЪ рдореВрд▓реНрдп рд╕реБрд░рдХреНрд╖рд╛ рдмрдврд╝рд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЧрдгрдирд╛ рдореЗрдВ рднреА рдХрдард┐рди рд╣реИ, рдпрд╣ рд▓рдЧрднрдЧ n log n рддрд░рд╣ рд╣реИ)ред

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕реАрдХреЗрдХреЗрдПрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЧрдгрдирд╛ рд╢реЛрд░ рд╣реИ ред рдЗрд╕рд▓рд┐рдП, рдкрд░рд┐рдгрд╛рдо рдЕрдиреБрдорд╛рдирд┐рдд рд╣реИрдВ, рдФрд░ рдзреНрдпрд╛рди рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдкрд░реНрдпрд╛рдкреНрдд рд╕рдЯреАрдХрддрд╛ рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рдП рддрд╛рдХрд┐ рдкрд░рд┐рдгрд╛рдо рдХреА рд╢реБрджреНрдзрддрд╛ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред

рджреВрд╕рд░реА рдУрд░, рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧ рдкреИрдХреЗрдЬ рдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП рдРрд╕реЗ рдкреНрд░рддрд┐рдмрдВрдз рдЕрд╕рд╛рдорд╛рдиреНрдп рдирд╣реАрдВ рд╣реИрдВред GPU рдХреА рддрд░рд╣ рд╡рд┐рд╢реЗрд╖ рддреНрд╡рд░рдХ рднреА рдЖрдорддреМрд░ рдкрд░ рдирдВрдмрд░ рд╡реИрдХреНрдЯрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдХрдИ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП, рдлрд╝реНрд▓реЛрдЯрд┐рдВрдЧ рдкреЙрдЗрдВрдЯ рдирдВрдмрд░ рдХрднреА-рдХрднреА рдЪрдпрди рдПрд▓реНрдЧреЛрд░рд┐рджрдо, рдорд▓реНрдЯреАрдереНрд░реЗрдбрд┐рдВрдЧ, рдФрд░ рдЗрд╕реА рддрд░рд╣ рдХреЗ рдкреНрд░рднрд╛рд╡ рдХреЗ рдХрд╛рд░рдг рд╢реЛрд░ рдХрд░рддреЗ рд╣реИрдВред рдореИрдВ рдЗрд╕ рдмрд╛рдд рдкрд░ рдЬреЛрд░ рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдлреНрд▓реЛрдЯрд┐рдВрдЧ рдкреЙрдЗрдВрдЯ рдирдВрдмрд░реЛрдВ рдХреЗ рд╕рд╛рде рдЕрдВрдХрдЧрдгрд┐рддреАрдп рдЧрдгрдирд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд░реВрдк рд╕реЗ рдирд┐рдпрддрд╛рддреНрдордХ рд╣реИ, рднрд▓реЗ рд╣реА рдпрд╣ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рдХрд╛рд░рдг рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╕реАрдХреЗрдХреЗрдПрд╕ рдЖрджрд┐рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╢реЛрд░ рд╣реИрдВред рд▓реЗрдХрд┐рди рд╢рд╛рдпрдж рдпрд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рд╢реЛрд░ рдЙрддрдирд╛ рдбрд░рд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИ рдЬрд┐рддрдирд╛ рдпрд╣ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИред

рдЕрдм рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдЖрдк рдЬреВрд▓рд┐рдпрд╛ рдореЗрдВ рдЗрди рдСрдкрд░реЗрд╢рдиреЛрдВ рдХреЛ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдзреНрдпрд╛рди рджреЗрдВ: рдмрд╣реБрдд рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрди рдкрд░рд┐рдЪрд╛рд▓рдиреЛрдВ рдХреЗ рд╕рд╛рде рд╣рдо рдХреЗрд╡рд▓ REPL рдореЗрдВ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдЪрд┐рддреНрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ)ред

 julia> using ToyFHE # Let's play with 8 element vectors julia> N = 8; # Choose some parameters - we'll talk about it later julia> тДЫ = NegacyclicRing(2N, (40, 40, 40)) тДдтВБтВГтВВтВЙтВВтВВтВЗтВЙтВЙтВЗтВЕтВЖтВИтВАтВИтВБтВДтВЕтВЗтВДтВАтВВтВЗтВАтВБтВВтВАтВЗтВБтВАтВДтВВтВДтВИтВВтВЕтВЗ/(x┬╣тБ╢ + 1) # We'll use CKKS julia> params = CKKSParams(тДЫ) CKKS parameters # We need to pick a scaling factor for a numbers - again we'll talk about that later julia> Tscale = FixedRational{2^40} FixedRational{1099511627776,T} where T # Let's start with a plain Vector of zeros julia> plain = CKKSEncoding{Tscale}(zero(тДЫ)) 8-element CKKSEncoding{FixedRational{1099511627776,T} where T} with indices 0:7: 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im # Ok, we're ready to get started, but first we'll need some keys julia> kp = keygen(params) CKKS key pair julia> kp.priv CKKS private key julia> kp.pub CKKS public key # Alright, let's encrypt some things: julia> foreach(i->plain[i] = i+1, 0:7); plain 8-element CKKSEncoding{FixedRational{1099511627776,T} where T} with indices 0:7: 1.0 + 0.0im 2.0 + 0.0im 3.0 + 0.0im 4.0 + 0.0im 5.0 + 0.0im 6.0 + 0.0im 7.0 + 0.0im 8.0 + 0.0im julia> c = encrypt(kp.pub, plain) CKKS ciphertext (length 2, encoding CKKSEncoding{FixedRational{1099511627776,T} where T}) # And decrypt it again julia> decrypt(kp.priv, c) 8-element CKKSEncoding{FixedRational{1099511627776,T} where T} with indices 0:7: 0.9999999999995506 - 2.7335193113350057e-16im 1.9999999999989408 - 3.885780586188048e-16im 3.000000000000205 + 1.6772825551165524e-16im 4.000000000000538 - 3.885780586188048e-16im 4.999999999998865 + 8.382500573679615e-17im 6.000000000000185 + 4.996003610813204e-16im 7.000000000001043 - 2.0024593503998215e-16im 8.000000000000673 + 4.996003610813204e-16im # Note that we had some noise. Let's go through all the primitive operations we'll need: julia> decrypt(kp.priv, c+c) 8-element CKKSEncoding{FixedRational{1099511627776,T} where T} with indices 0:7: 1.9999999999991012 - 5.467038622670011e-16im 3.9999999999978817 - 7.771561172376096e-16im 6.00000000000041 + 3.354565110233105e-16im 8.000000000001076 - 7.771561172376096e-16im 9.99999999999773 + 1.676500114735923e-16im 12.00000000000037 + 9.992007221626409e-16im 14.000000000002085 - 4.004918700799643e-16im 16.000000000001346 + 9.992007221626409e-16im julia> csq = c*c CKKS ciphertext (length 3, encoding CKKSEncoding{FixedRational{1208925819614629174706176,T} where T}) julia> decrypt(kp.priv, csq) 8-element CKKSEncoding{FixedRational{1208925819614629174706176,T} where T} with indices 0:7: 0.9999999999991012 - 2.350516767363621e-15im 3.9999999999957616 - 5.773159728050814e-15im 9.000000000001226 - 2.534464540987068e-15im 16.000000000004306 - 2.220446049250313e-15im 24.99999999998865 + 2.0903753311370056e-15im 36.00000000000222 + 4.884981308350689e-15im 49.000000000014595 + 1.0182491378134327e-15im 64.00000000001077 + 4.884981308350689e-15im 

рдЗрддрдирд╛ рд╕рд░рд▓! рдПрдХ рдЪреМрдХрд╕ рдкрд╛рдардХ рджреЗрдЦ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ CSQ рдкрд┐рдЫрд▓реЗ рд╕рд┐рдлрд░ рд╕реЗ рдереЛрдбрд╝рд╛ рдЕрд▓рдЧ рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рд╕рд┐рдлрд░рдЯреЗрдХреНрд╕реНрдЯ рдХреА "рд▓рдВрдмрд╛рдИ 3" рд╣реИ рдФрд░ рд╕реНрдХреЗрд▓ рдмрд╣реБрдд рдмрдбрд╝рд╛ рд╣реИред рдпрд╣ рдХреНрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА рдХреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕рдХрд╛ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдЗрд╕ рд▓реЗрдЦ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░ рд╣реИред рдпрд╣ рдХрд╣рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдЧрдгрдирд╛рдУрдВ рдХреЛ рдЬрд╛рд░реА рд░рдЦрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛ "рдЬрдЧрд╣" рд╕рд┐рдлрд░рдПрдХреНрд╕ рдореЗрдВ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рдПрдЧреАред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рд╣рдо рджреЛ рдмрдврд╝реЗ рд╣реБрдП рдореВрд▓реНрдпреЛрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЛ рдХрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 # To get back down to length 2, we need to `keyswitch` (aka # relinerarize), which requires an evaluation key. Generating # this requires the private key. In a real application we would # have generated this up front and sent it along with the encrypted # data, but since we have the private key, we can just do it now. julia> ek = keygen(EvalMultKey, kp.priv) CKKS multiplication key julia> csq_length2 = keyswitch(ek, csq) CKKS ciphertext (length 2, encoding CKKSEncoding{FixedRational{1208925819614629174706176,T} where T}) # Getting the scale back down is done using modswitching. julia> csq_smaller = modswitch(csq_length2) CKKS ciphertext (length 2, encoding CKKSEncoding{FixedRational{1.099511626783e12,T} where T}) # And it still decrypts correctly (though note we've lost some precision) julia> decrypt(kp.priv, csq_smaller) 8-element CKKSEncoding{FixedRational{1.099511626783e12,T} where T} with indices 0:7: 0.9999999999802469 - 5.005163520332181e-11im 3.9999999999957723 - 1.0468514951188039e-11im 8.999999999998249 - 4.7588542623100616e-12im 16.000000000023014 - 1.0413447889166631e-11im 24.999999999955193 - 6.187833723406491e-12im 36.000000000002345 + 1.860733715346631e-13im 49.00000000001647 - 1.442396043149794e-12im 63.999999999988695 - 1.0722489563648028e-10im 

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, modswitching (рдорд╛рдкрд╛рдВрдХ рд╕реНрд╡рд┐рдЪрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдХрдо, рдореЙрдбреНрдпреВрд▓ рд╕реНрд╡рд┐рдЪрд┐рдВрдЧ) рд╕рд╛рдЗрдлрд░рдЯреЗрдХреНрд╕реНрдЯ рдореЙрдбреНрдпреВрд▓ рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рдХрдо рдХрд░рддрд╛ рд╣реИ, рддрд╛рдХрд┐ рд╣рдо рдЗрд╕реЗ рдЕрдирд┐рд╢реНрдЪрд┐рдд рдХрд╛рд▓ рддрдХ рдЬрд╛рд░реА рдирд╣реАрдВ рд░рдЦ рд╕рдХреЗрдВ (рд╣рдо рдХреБрдЫ рд╣рдж рддрдХ рд╣реЛрдореНрдпреЛрдореЛрд░реНрдлрд┐рдХ рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдпреЛрдЬрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ):

 julia> тДЫ # Remember the ring we initially created тДдтВБтВГтВВтВЙтВВтВВтВЗтВЙтВЙтВЗтВЕтВЖтВИтВАтВИтВБтВДтВЕтВЗтВДтВАтВВтВЗтВАтВБтВВтВАтВЗтВБтВАтВДтВВтВДтВИтВВтВЕтВЗ/(x┬╣тБ╢ + 1) julia> ToyFHE.ring(csq_smaller) # It shrunk! тДдтВБтВВтВАтВИтВЙтВВтВЕтВИтВВтВАтВБтВДтВДтВЕтВЙтВГтВЗтВЗтВЙтВГтВГтВБтВЕтВЕтВГ/(x┬╣тБ╢ + 1)</code>     тАФ  (rotations).      keyswitch,       (evaluation key,     ): <source lang="julia">julia> gk = keygen(GaloisKey, kp.priv; steps=2) CKKS galois key (element 25) julia> decrypt(circshift(c, gk)) decrypt(kp, circshift(c, gk)) 8-element CKKSEncoding{FixedRational{1099511627776,T} where T} with indices 0:7: 7.000000000001042 + 5.68459112632516e-16im 8.000000000000673 + 5.551115123125783e-17im 0.999999999999551 - 2.308655353580721e-16im 1.9999999999989408 + 2.7755575615628914e-16im 3.000000000000205 - 6.009767921608429e-16im 4.000000000000538 + 5.551115123125783e-17im 4.999999999998865 + 4.133860996136768e-17im 6.000000000000185 - 1.6653345369377348e-16im # And let's compare to doing the same on the plaintext julia> circshift(plain, 2) 8-element OffsetArray(::Array{Complex{Float64},1}, 0:7) with eltype Complex{Float64} with indices 0:7: 7.0 + 0.0im 8.0 + 0.0im 1.0 + 0.0im 2.0 + 0.0im 3.0 + 0.0im 4.0 + 0.0im 5.0 + 0.0im 6.0 + 0.0im 

рд╣рдордиреЗ HE рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рдЙрдкрдпреЛрдЧ рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ рдХрд╡рд░ рдХреАрдВред рд▓реЗрдХрд┐рди рддрдВрддреНрд░рд┐рдХрд╛ рдиреЗрдЯрд╡рд░реНрдХ рдкреВрд░реНрд╡рд╛рдиреБрдорд╛рдиреЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрди рдЖрджрд┐рдорддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдЗрдП рдЗрд╕реЗ рд╕реАрдЦрдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рджреЗрдЦреЗрдВред

рдорд╢реАрди рд╕реАрдЦрдиреЗ рдХрд╛ рдореЙрдбрд▓


рдпрджрд┐ рдЖрдк рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧ рдпрд╛ рдлрд╝реНрд▓рдХреНрд╕.рдЬреНрд▓ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдореИрдВ рдлрд╝реНрд▓рдХреНрд╕.рдЬреНрд▓ рдбреЙрдХреНрдпреВрдореЗрдВрдЯреЗрд╢рди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рддреНрд╡рд░рд┐рдд рд░рди рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ рдпрд╛ рдорд╢реАрди рд▓рд░реНрдирд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдореБрдлреНрдд рдкрд░рд┐рдЪрдп рджреЗрдЦрддрд╛ рд╣реВрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдХреЗрд╡рд▓ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдореЙрдбрд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВрдЧреЗред

рдЪрд▓реЛ рдлреНрд▓рдХреНрд╕ рдЪрд┐рдбрд╝рд┐рдпрд╛рдШрд░ рд╕реЗ рджреГрдврд╝ рддрдВрддреНрд░рд┐рдХрд╛ рдиреЗрдЯрд╡рд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдбреЗрдЯрд╛ рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдЪрдХреНрд░ рдХреЛ рдЖрдЧреЗ рдмрдврд╝рд╛рдПрдВрдЧреЗ, рдмрд╕ рдореЙрдбрд▓ рдХреЛ рдереЛрдбрд╝рд╛ рд╕реЗрдЯ рдХрд░реЗрдВред рдпрд╣рд╛рдБ рдпрд╣ рд╣реИ:

 function reshape_and_vcat(x) let y=reshape(x, 64, 4, size(x, 4)) vcat((y[:,i,:] for i=axes(y,2))...) end end model = Chain( # First convolution, operating upon a 28x28 image Conv((7, 7), 1=>4, stride=(3,3), x->x.^2), reshape_and_vcat, Dense(256, 64, x->x.^2), Dense(64, 10), ) 

рдпрд╣ рдПрдХ рд╣реА рдореЙрдбрд▓ рд╣реИ рдЬреИрд╕реЗ рдХрд┐ "рд╕рд┐рдХреНрдпреЛрд░ рдЖрдЙрдЯрд╕реЛрд░реНрд╕реНрдб рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХрдВрдкреНрдпреБрдЯреЗрд╢рди рдПрдВрдб рдПрдкреНрд▓реАрдХреЗрд╢рди рдЯреВ рдиреНрдпреВрд░рд▓ рдиреЗрдЯрд╡рд░реНрдХреНрд╕" , рдЬреЛ рджреЛ рдЕрдВрддрд░реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╣реА рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлрд┐рдХ рд╕реНрдХреАрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ: 1) рд╕рд░рд▓рддрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рд╕реНрд╡рдпрдВ рдореЙрдбрд▓ рдХреЛ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдФрд░ 2) рдкреНрд░рддреНрдпреЗрдХ рд▓реЗрдпрд░ рдХреЗ рдмрд╛рдж рдмрд╛рдпреЗрд╕рд┐рдпрди рд╡реИрдХреНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдпрд╣ рдлреНрд▓рдХреНрд╕ рдореЗрдВ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдЙрд▓реНрд▓реЗрдЦрд┐рдд рдХрд╛рд░реНрдп рдореЗрдВ рдерд╛ред рд╢рд╛рдпрдж, рджреВрд╕рд░реЗ рдмрд┐рдВрджреБ рдХреЗ рдХрд╛рд░рдг, рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рдХреЗ рдкрд░реАрдХреНрд╖рдг рд╕реЗрдЯ рдкрд░ рд╕рдЯреАрдХрддрд╛ рдереЛрдбрд╝реА рдЕрдзрд┐рдХ рд╣реЛ рдЧрдИ (98.6% рдмрдирд╛рдо 98.1%), рд▓реЗрдХрд┐рди рд╣рд╛рдЗрдкрд░рдкрд░рдореЗрдЯреНрд░рд┐рдХ рдЕрдВрддрд░ рднреА рдЗрд╕рдХрд╛ рдХрд╛рд░рдг рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдЕрд╕рд╛рдорд╛рдиреНрдп (рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдорд╢реАрди рд╕реАрдЦрдиреЗ рдХрд╛ рдЕрдиреБрднрд╡ рд╣реИ) x.^2 рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдХрд╛рд░реНрдпред рдЬреНрдпрд╛рджрд╛рддрд░ рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рд╡реЗ tanh , relu рдпрд╛ рдХреБрдЫ рдЕрдзрд┐рдХ рдХрд╛рд▓реНрдкрдирд┐рдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдпрджреНрдпрдкрд┐ рдЗрди рдХрд╛рд░реНрдпреЛрдВ (рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ relu ) рдХреА рдЧрдгрдирд╛ рд╕рд╛рдзрд╛рд░рдг рдкрд╛рда рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрд╕рд╛рдиреА рд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЙрдиреНрд╣реЗрдВ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рд░реВрдк рдореЗрдВ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдЕрдзрд┐рдХ рдХрдореНрдкреНрдпреВрдЯреЗрд╢рдирд▓ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ (рд╣рдо рдЖрдорддреМрд░ рдкрд░ рдмрд╣реБрдкрдж рд╕рдиреНрдирд┐рдХрдЯрди рдХрд╛ рдЕрдиреБрдорд╛рди рд▓рдЧрд╛рддреЗ рд╣реИрдВ)ред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ x.^2 рдорд╣рд╛рди рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

рд╢реЗрд╖ рд╢рд┐рдХреНрд╖рдг рдЪрдХреНрд░ рд╕рдорд╛рди рд░рд╣рд╛ред рд╣рдордиреЗ рд╣рд╛рдирд┐-рдлрд╝рдВрдХреНрд╢рди logitcrossentropy рд▓рд┐рдП рдореЙрдбрд▓ рд╕реЗ softmax рдХреЛ рд╣рдЯрд╛ рджрд┐рдпрд╛ (рдЖрдк рдЗрд╕реЗ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдХреНрд▓рд╛рдЗрдВрдЯ рдкрд░ рдбрд┐рдХреНрд░рд┐рдкреНрд╢рди рдХреЗ рдмрд╛рдж рд╕реЙрдлреНрдЯрдореИрдХреНрд╕ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ)ред рдореЙрдбрд▓ рдХреЗ рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдкреВрд░рд╛ рдХреЛрдб GitHub рдкрд░ рд╣реИ , рдпрд╣ рдХрд┐рд╕реА рднреА рдирдП рд╡реАрдбрд┐рдпреЛ рдХрд╛рд░реНрдб рдкрд░ рдХреБрдЫ рд╣реА рдорд┐рдирдЯреЛрдВ рдореЗрдВ рдЪрд▓рддрд╛ рд╣реИред

рдкреНрд░рднрд╛рд╡реА рд╕рдВрдЪрд╛рд▓рди


рдЕрдм рд╣рдореЗрдВ рдкрддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рдХреМрди рд╕реЗ рд╕рдВрдЪрд╛рд▓рди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:

  • рдердХреНрдХреЗред
  • рддрддреНрд╡ рд╡рд░реНрдЧред
  • рдореИрдЯреНрд░рд┐рдХреНрд╕ рдЧреБрдгрдиред

рд╕реНрдХреНрд╡реЗрд░рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рд╕рд░рд▓ рд╣реИ, рд╣рдордиреЗ рдкрд╣рд▓реЗ рд╣реА рдКрдкрд░ рдЬрд╛рдВрдЪ рдХреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рджреЛ рдЕрдиреНрдп рдСрдкрд░реЗрд╢рдиреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдбреЗрдЯрд╛ рдкреИрдХреЗрдЯ рдХреА рд▓рдВрдмрд╛рдИ 64 рд╣реИ (рдЖрдк рдиреЛрдЯрд┐рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдореЙрдбрд▓ рдкреИрд░рд╛рдореАрдЯрд░ рдФрд░ рдкреИрдХреЗрдЯ рдХрд╛ рдЖрдХрд╛рд░ рдЗрд╕рд▓рд┐рдП рдЪреБрдирд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ 4096-рддрддреНрд╡ рд╡реЗрдХреНрдЯрд░ рдХрд╛ рд▓рд╛рдн рдЙрдард╛рдпрд╛ рдЬрд╛ рд╕рдХреЗ рдЬреЛ рд╣рдордиреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдпрдерд╛рд░реНрдерд╡рд╛рджреА рд╡рд┐рдХрд▓реНрдк рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдерд╛)ред

рдЬрдорд╛рд╡рдЯ


рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рдЬрдорд╛рд╡рдЯ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдореВрд▓ рдЗрдирдкреБрдЯ рдРрд░реЗ рдХреА рдПрдХ рд╡рд┐рдВрдбреЛ (рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ 7x7) рд▓реЗрдВ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдВрдбреЛ рдПрд▓рд┐рдореЗрдВрдЯ рдХреЛ рдПрдХ рдХрдирд╡рд▓реНрд╢рди рдорд╛рд╕реНрдХ рддрддреНрд╡ рд╕реЗ рдЧреБрдгрд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдлрд┐рд░ рд╣рдо рд╡рд┐рдВрдбреЛ рдХреЛ рдХреБрдЫ рдЪрд░рдг рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ (рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЪрд░рдг 3 рд╣реИ, рдЕрд░реНрдерд╛рдд рд╣рдо 3 рддрддреНрд╡реЛрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ) рдФрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рджреЛрд╣рд░рд╛рддреЗ рд╣реИрдВ (рдПрдХ рд╣реА рджреГрдврд╝ рд╕рдВрдХрд▓реНрдк рдореБрдЦреМрдЯрд╛ рдХреЗ рд╕рд╛рде)ред рдЪрд░рдг (2, 2) рд╕рд╛рде 3x3 рджреГрдврд╝ рд╕рдВрдХрд▓реНрдк рдХреЗ рд▓рд┐рдП рдкреНрд░рдХреНрд░рд┐рдпрд╛ ( рд╕реНрд░реЛрдд ) рдХрд╛ рдПрдиреАрдореЗрд╢рди рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдиреАрд▓рд╛ рд╕рд░рдгреА - рдЗрдирдкреБрдЯ, рд╣рд░рд╛ - рдЖрдЙрдЯрдкреБрдЯ):


рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо рдЪрд╛рд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ "рдЪреИрдирд▓реЛрдВ" рдореЗрдВ рдХрдиреНрд╡реЗрдВрд╢рди рдХрд░рддреЗ рд╣реИрдВ (рдпрд╛рдиреА, рд╣рдо 3 рдмрд╛рд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдорд╛рд╕реНрдХ рдХреЗ рд╕рд╛рде рдХрдиреНрд╡рд░реНрд╕реЗрд╢рди рджреЛрд╣рд░рд╛рддреЗ рд╣реИрдВ)ред

рдЕрдм рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ, рдпрд╣ рдХреИрд╕реЗ рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИред рд╣рдо рднрд╛рдЧреНрдпрд╢рд╛рд▓реА рд╣реИрдВ рдХрд┐ рджреГрдврд╝ рд╕рдВрдХрд▓реНрдк рд╣рдорд╛рд░реЗ рдореЙрдбрд▓ рдореЗрдВ рдкрд╣рд▓рд╛ рдСрдкрд░реЗрд╢рди рд╣реИред рдирддреАрдЬрддрди, рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЧреНрд░рд╛рд╣рдХ рдкрд░ рдбреЗрдЯрд╛ рдХреЛ рдкреВрд░реНрд╡-рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдлрд┐рд░ рдЙрдиреНрд╣реЗрдВ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рд╡рдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдмрд┐рдирд╛)ред рдРрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ:

  • рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдХрдирд╡реЗрдВрд╢рди рд╡рд┐рдВрдбреЛ (рдЬреЛ рд╕реНрд░реЛрдд рдЫрд╡рд┐рдпреЛрдВ рд╕реЗ рдПрдХ 7x7 рдирдореВрдирд╛ рд╣реИ) рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдЗрдирдкреБрдЯ рдЫрд╡рд┐ рдХреЗ рд▓рд┐рдП 64 7x7 рдореИрдЯреНрд░рд┐рд╕реЗрд╕ рджреЗрддрд╛ рд╣реИред рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ 2 рдХреЗ рд╡реЗрддрди рд╡реГрджреНрдзрд┐ рдореЗрдВ 7x7 рд╡рд┐рдВрдбреЛ рдХреЗ рд▓рд┐рдП, 28x289 рдЫрд╡рд┐ рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 8x8 рдХрдирд╡рд▓реНрд╢рди рд╡рд┐рдВрдбреЛ рд╣реЛрдЧреАред
  • рдЖрдЗрдП рдПрдХ рд╡реЗрдХреНрдЯрд░ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рдВрдбреЛ рдореЗрдВ рд╕рдорд╛рди рдкрджреЛрдВ рдХреЛ рдЗрдХрдЯреНрдард╛ рдХрд░реЗрдВред рдпрд╣реА рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рдЫрд╡рд┐ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдкрд╛рд╕ 64-рддрддреНрд╡ рд╡реЗрдХреНрдЯрд░, рдпрд╛ 64x64 рддрддреНрд╡реЛрдВ рдХреЗ рдПрдХ рд╡реЗрдХреНрдЯрд░ рдХрд╛ рдЖрдХрд╛рд░ 64 рдХреЗ рдкреИрдХреЗрдЯ рдХреЗ рд▓рд┐рдП рд╣реЛрдЧрд╛ (рдХреБрд▓ 49 рдореИрдЯреНрд░рд┐рдХреНрд╕ 64x64)ред
  • рд╣рдо рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХрд░реЗрдВрдЧреЗред

рддрдм рдЬрдорд╛рд╡рдЯ рдмрд╕ рдЗрд╕реА рдореИрдЯреНрд░рд┐рдХреНрд╕ рддрддреНрд╡ рдХреЗ рд╕рд╛рде рдкреВрд░реЗ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдХреЗ рд╕реНрдХреЗрд▓рд░ рдЧреБрдгрди рдореЗрдВ рдмрджрд▓ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдмрд╛рдж рдореЗрдВ рд╕рднреА 49 рддрддреНрд╡реЛрдВ рдХреЛ рдЬреЛрдбрд╝ рджреЗрдВ, рд╣рдо рддрд╣ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдЗрд╕ рд░рдгрдиреАрддрд┐ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рддрд░рд╣ рд▓рдЧ рд╕рдХрддрд╛ рд╣реИ (рд╕рд╛рджреЗ рдкрд╛рда рдореЗрдВ):

 function public_preprocess(batch) ka = OffsetArray(0:7, 0:7) # Create feature extracted matrix I = [[batch[iтА▓*3 .+ (1:7), jтА▓*3 .+ (1:7), 1, k] for iтА▓=ka, jтА▓=ka] for k = 1:64] # Reshape into the ciphertext Iс╡вт▒╝ = [[I[k][l...][i,j] for k=1:64, l=product(ka, ka)] for i=1:7, j=1:7] end Iс╡вт▒╝ = public_preprocess(batch) # Evaluate the convolution weights = model.layers[1].weight conv_weights = reverse(reverse(weights, dims=1), dims=2) conved = [sum(Iс╡вт▒╝[i,j]*conv_weights[i,j,1,channel] for i=1:7, j=1:7) for channel = 1:4] conved = map(((x,b),)->x .+ b, zip(conved, model.layers[1].bias)) 

рдпрд╣ (рдЖрдпрд╛рдо рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдореЙрдбреНрдпреВрд▓) (modulo - рдЖрдХрд╛рд░реЛрдВ рдХреЗ рдХреНрд░рдо рдХреЛ рдмрджрд▓рдирд╛) рдСрдкрд░реЗрд╢рди model.layers[1](batch) рдХреЗ рд╕рдорд╛рди рдЙрддреНрддрд░ рджреЗрддрд╛ рд╣реИред model.layers[1](batch) ред

рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рдСрдкрд░реЗрд╢рди рдЬреЛрдбрд╝реЗрдВ:

 Iс╡вт▒╝ = public_preprocess(batch) C_Iс╡вт▒╝ = map(Iс╡вт▒╝) do Iij plain = CKKSEncoding{Tscale}(zero(plaintext_space(ckks_params))) plain .= OffsetArray(vec(Iij), 0:(N├╖2-1)) encrypt(kp, plain) end weights = model.layers[1].weight conv_weights = reverse(reverse(weights, dims=1), dims=2) conved3 = [sum(C_Iс╡вт▒╝[i,j]*conv_weights[i,j,1,channel] for i=1:7, j=1:7) for channel = 1:4] conved2 = map(((x,b),)->x .+ b, zip(conved3, model.layers[1].bias)) conved1 = map(ToyFHE.modswitch, conved2) 

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣рд╛рдВ рдХреАрд╕реНрд╡рд┐рдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рднрд╛рд░ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕рд┐рдлрд░рдЯреЗрдХреНрд╕реНрдЯ рдХреА рд▓рдВрдмрд╛рдИ рдирд╣реАрдВ рдмрдврд╝рд╛рддреЗ рд╣реИрдВред

рдореИрдЯреНрд░рд┐рдХреНрд╕ рдЧреБрдгрди


рдореИрдЯреНрд░рд┐рдХреНрд╕ рдЧреБрдгрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реБрдП, рд╣рдо рдЧреБрдгрди рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рдХреЗ рдХреНрд░рдо рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╡реЗрдХреНрдЯрд░ рдореЗрдВ рддрддреНрд╡реЛрдВ рдХреЗ рд░реЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╡реЗрдХреНрдЯрд░ рдореЗрдВ рдореИрдЯреНрд░рд┐рдХреНрд╕ рддрддреНрд╡реЛрдВ рдХреЗ рдкрдВрдХреНрддрд┐-рд╡рд╛рд░ рдкреНрд▓реЗрд╕рдореЗрдВрдЯ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдпрджрд┐ рд╣рдо рд╡реЗрдХреНрдЯрд░ рдХреЛ рдкрдВрдХреНрддрд┐ рдЖрдХрд╛рд░ рдХреЗ рдХрдИ рднрд╛рдЧ рд╕реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдХреЙрд▓рдо рдШреБрдорд╛рд╡ рдХрд╛ рдкреНрд░рднрд╛рд╡ рдорд┐рд▓рддрд╛ рд╣реИ, рдЬреЛ рдореИрдЯреНрд░рд┐рдХреНрд╕ рдЧреБрдгрди (рдХрдо рд╕реЗ рдХрдо рд╡рд░реНрдЧ рдореИрдЯреНрд░рд┐рд╕реЗрд╕) рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкрд░реНрдпрд╛рдкреНрдд рдЖрджрд┐рдо рд╣реИред рдЖрдЗрдП рдХреЛрд╢рд┐рд╢ рдХрд░рддреЗ рд╣реИрдВ:

 function matmul_square_reordered(weights, x) sum(1:size(weights, 1)) do k # We rotate the columns of the LHS and take the diagonal weight_diag = diag(circshift(weights, (0,(k-1)))) # We rotate the rows of the RHS x_rotated = circshift(x, (k-1,0)) # We do an elementwise, broadcast multiply weight_diag .* x_rotated end end function matmul_reorderd(weights, x) sum(partition(1:256, 64)) do range matmul_square_reordered(weights[:, range], x[range, :]) end end fc1_weights = model.layers[3].W x = rand(Float64, 256, 64) @assert (fc1_weights*x) тЙИ matmul_reorderd(fc1_weights, x) 

рдмреЗрд╢рдХ, рд╕рд╛рдорд╛рдиреНрдп рдореИрдЯреНрд░рд┐рдХреНрд╕ рдЧреБрдгрди рдХреЗ рд▓рд┐рдП, рдХреБрдЫ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рд▓реЗрдХрд┐рди рдЕрднреА рдХреЗ рд▓рд┐рдП рдпрд╣ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред

рддрдХрдиреАрдХ рдореЗрдВ рд╕реБрдзрд╛рд░


рдЕрдм рд╣рдорд╛рд░реА рддрдХрдиреАрдХ рдХреЗ рд╕рднреА рдШрдЯрдХ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдкреВрд░рд╛ рдХреЛрдб рд╣реИ (рдЪрдпрди рд╡рд┐рдХрд▓реНрдк рдФрд░ рдЗрд╕реА рддрд░рд╣ рдХреА рдЪреАрдЬреЛрдВ рдХреЛ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛):

 ek = keygen(EvalMultKey, kp.priv) gk = keygen(GaloisKey, kp.priv; steps=64) Iс╡вт▒╝ = public_preprocess(batch) C_Iс╡вт▒╝ = map(Iс╡вт▒╝) do Iij plain = CKKSEncoding{Tscale}(zero(plaintext_space(ckks_params))) plain .= OffsetArray(vec(Iij), 0:(N├╖2-1)) encrypt(kp, plain) end weights = model.layers[1].weight conv_weights = reverse(reverse(weights, dims=1), dims=2) conved3 = [sum(C_Iс╡вт▒╝[i,j]*conv_weights[i,j,1,channel] for i=1:7, j=1:7) for channel = 1:4] conved2 = map(((x,b),)->x .+ b, zip(conved3, model.layers[1].bias)) conved1 = map(ToyFHE.modswitch, conved2) Csqed1 = map(x->x*x, conved1) Csqed1 = map(x->keyswitch(ek, x), Csqed1) Csqed1 = map(ToyFHE.modswitch, Csqed1) function encrypted_matmul(gk, weights, x::ToyFHE.CipherText) result = repeat(diag(weights), inner=64).*x rotated = x for k = 2:64 rotated = ToyFHE.rotate(gk, rotated) result += repeat(diag(circshift(weights, (0,(k-1)))), inner=64) .* rotated end result end fq1_weights = model.layers[3].W Cfq1 = sum(enumerate(partition(1:256, 64))) do (i,range) encrypted_matmul(gk, fq1_weights[:, range], Csqed1[i]) end Cfq1 = Cfq1 .+ OffsetArray(repeat(model.layers[3].b, inner=64), 0:4095) Cfq1 = modswitch(Cfq1) Csqed2 = Cfq1*Cfq1 Csqed2 = keyswitch(ek, Csqed2) Csqed2 = modswitch(Csqed2) function naive_rectangular_matmul(gk, weights, x) @assert size(weights, 1) < size(weights, 2) weights = vcat(weights, zeros(eltype(weights), size(weights, 2)-size(weights, 1), size(weights, 2))) encrypted_matmul(gk, weights, x) end fq2_weights = model.layers[4].W Cresult = naive_rectangular_matmul(gk, fq2_weights, Csqed2) Cresult = Cresult .+ OffsetArray(repeat(vcat(model.layers[4].b, zeros(54)), inner=64), 0:4095) 

рдпрд╣ рдмрд╣реБрдд рд╕рд╛рдл рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдкрдиреЗ рдпрд╣ рд╕рдм рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рд╣рд░ рдХрджрдо рдХреЛ рд╕рдордЭрдирд╛ рдЪрд╛рд╣рд┐рдПред
рдЕрдм рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдХрд┐ рдХреНрдпрд╛ рд╕рд╛рд░ рд╣рдорд╛рд░реЗ рдЬреАрд╡рди рдХреЛ рд╕рд░рд▓ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдо рдХрд╛рд░реНрдЯреЛрдЧреНрд░рд╛рдлреА рдФрд░ рдорд╢реАрди рд╕реАрдЦрдиреЗ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХреЛ рдЫреЛрдбрд╝ рд░рд╣реЗ рд╣реИрдВ рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреА рдУрд░ рдмрдврд╝ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рдЪрд▓рд┐рдП рдЗрд╕ рддрдереНрдп рдХрд╛ рд▓рд╛рдн рдЙрдард╛рддреЗ рд╣реИрдВ рдХрд┐ рдЬреВрд▓рд┐рдпрд╛ рдЖрдкрдХреЛ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╕рд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдФрд░ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЕрдкрдиреЗ рд╕рд░рдгреА рдкреНрд░рдХрд╛рд░ рдореЗрдВ рдХрдирд╡рд▓реНрд╢рди рдирд┐рдХрд╛рд▓рдиреЗ рдХреА рдкреВрд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЕрд▓рдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

 using BlockArrays """ ExplodedConvArray{T, Dims, Storage} <: AbstractArray{T, 4} Represents a an `nxmx1xb` array of images, but rearranged into a series of convolution windows. Evaluating a convolution compatible with `Dims` on this array is achievable through a sequence of scalar multiplications and sums on the underling storage. """ struct ExplodedConvArray{T, Dims, Storage} <: AbstractArray{T, 4} # sx*sy matrix of b*(dx*dy) matrices of extracted elements # where (sx, sy) = kernel_size(Dims) # (dx, dy) = output_size(DenseConvDims(...)) cdims::Dims x::Matrix{Storage} function ExplodedConvArray{T, Dims, Storage}(cdims::Dims, storage::Matrix{Storage}) where {T, Dims, Storage} @assert all(==(size(storage[1])), size.(storage)) new{T, Dims, Storage}(cdims, storage) end end Base.size(ex::ExplodedConvArray) = (NNlib.input_size(ex.cdims)..., 1, size(ex.x[1], 1)) function ExplodedConvArray{T}(cdims, batch::AbstractArray{T, 4}) where {T} x, y = NNlib.output_size(cdims) kx, ky = NNlib.kernel_size(cdims) stridex, stridey = NNlib.stride(cdims) kax = OffsetArray(0:x-1, 0:x-1) kay = OffsetArray(0:x-1, 0:x-1) I = [[batch[iтА▓*stridex .+ (1:kx), jтА▓*stridey .+ (1:ky), 1, k] for iтА▓=kax, jтА▓=kay] for k = 1:size(batch, 4)] Iс╡вт▒╝ = [[I[k][l...][i,j] for k=1:size(batch, 4), l=product(kax, kay)] for (i,j) in product(1:kx, 1:ky)] ExplodedConvArray{T, typeof(cdims), eltype(Iс╡вт▒╝)}(cdims, Iс╡вт▒╝) end function NNlib.conv(x::ExplodedConvArray{<:Any, Dims}, weights::AbstractArray{<:Any, 4}, cdims::Dims) where {Dims<:ConvDims} blocks = reshape([ Base.ReshapedArray(sum(xx[i,j]*weights[i,j,1,channel] for i=1:7, j=1:7), (NNlib.output_size(cdims)...,1,size(x, 4)), ()) for channel = 1:4 ],(1,1,4,1)) BlockArrays._BlockArray(blocks, BlockArrays.BlockSizes([8], [8], [1,1,1,1], [64])) end 

рдпрд╣рд╛рдБ рд╣рдордиреЗ рдлрд┐рд░ рд╕реЗ BlockArrays рдХрд╛ рдЙрдкрдпреЛрдЧ BlockArrays рд╕рд░рдгреА рдХреЛ рдЪрд╛рд░ рдХреЛрдб 8x8x1x64 рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ 8x8x1x64 рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рд╣реИред рдЕрдм рдкрд╣рд▓реЗ рдЪрд░рдг рдХреА рдкреНрд░рд╕реНрддреБрддрд┐ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рд╣реЛ рдЧрдИ рд╣реИ, рдХрдо рд╕реЗ рдХрдо рдЕрдирдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде:

 julia> cdims = DenseConvDims(batch, model.layers[1].weight; stride=(3,3), padding=(0,0,0,0), dilation=(1,1)) DenseConvDims: (28, 28, 1) * (7, 7) -> (8, 8, 4), stride: (3, 3) pad: (0, 0, 0, 0), dil: (1, 1), flip: false julia> a = ExplodedConvArray{eltype(batch)}(cdims, batch); julia> model(a) 10├Ч64 Array{Float32,2}: [snip] 

рдЕрдм рд╣рдо рдЗрд╕реЗ рдПрдиреНрдХреНрд░рд┐рдкреНрд╢рди рд╕реЗ рдХреИрд╕реЗ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ? рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЪрд╛рд╣рд┐рдП:

  1. рд╕рдВрд░рдЪрдирд╛ ( ExplodedConvArray ) рдХреЛ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХрд░реЗрдВ рддрд╛рдХрд┐ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рд╕рд┐рдлрд░рдЯреЗрдХреНрд╕реНрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде рд╕рдВрдЪрд╛рд▓рди рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░реЗрдЧрд╛ рдХрд┐ рдореВрд▓ рд╕рдВрд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде рдлрд╝рдВрдХреНрд╢рди рдХреНрдпрд╛ рдХрд░реЗрдЧрд╛, рдФрд░ рд╣реЛрдореЛрдореЛрд░реНрдлрд┐рдХ рд░реВрдк рд╕реЗ рдПрдХ рд╣реА рдХрд╛рд░реНрдп рдХрд░реЗрдВред
  2. рдПрдХ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рд╕рдВрджрд░реНрдн рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░реЗрдВред

рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдЬреВрд▓рд┐рдпрд╛ рд╣рдореЗрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдореВрд░реНрдд рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ: рдПрдХ рд╕рдВрдХрд▓рдХ рдкреНрд▓рдЧрдЗрди рдЬреЛ рдХреИрд╕реЗрдЯ.рдЬреЗрд▓ рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдореИрдВрдиреЗ рдЖрдкрдХреЛ рдпрд╣ рдирд╣реАрдВ рдмрддрд╛рдпрд╛ рдХрд┐ рдпрд╣ рдХреНрдпрд╛ рд╣реИ рдФрд░ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдореИрдВ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдХрд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рд╕рдВрджрд░реНрдн рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, Encrypted , рдФрд░ рдлрд┐рд░ рдпрд╣ рдирд┐рдпрдореЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рд╕рдВрджрд░реНрдн рдореЗрдВ рд╕рдВрдЪрд╛рд▓рди рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЗрд╕реЗ рджреВрд╕рд░реА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рд▓рд┐рдП рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ:

 # Define Matrix multiplication between an array and an encrypted block array function (*::Encrypted{typeof(*)})(a::Array{T, 2}, b::Encrypted{<:BlockArray{T, 2}}) where {T} sum(a*b for (i,range) in enumerate(partition(1:size(a, 2), size(b.blocks[1], 1)))) end # Define Matrix multiplication between an array and an encrypted array function (*::Encrypted{typeof(*)})(a::Array{T, 2}, b::Encrypted{Array{T, 2}}) where {T} result = repeat(diag(a), inner=size(a, 1)).*x rotated = b for k = 2:size(a, 2) rotated = ToyFHE.rotate(GaloisKey(*), rotated) result += repeat(diag(circshift(a, (0,(k-1)))), inner=size(a, 1)) .* rotated end result end 

рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЙрдкрд░реНрдпреБрдХреНрдд рд╕рднреА рдХреЛ рдореИрдиреБрдЕрд▓ рдХрд╛рдо рдХреА рдиреНрдпреВрдирддрдо рд░рд╛рд╢рд┐ рдХреЗ рд╕рд╛рде рд▓рд┐рдЦ рд╕рдХреЗрдЧрд╛:

 kp = keygen(ckks_params) ek = keygen(EvalMultKey, kp.priv) gk = keygen(GaloisKey, kp.priv; steps=64) # Create evaluation context ctx = Encrypted(ek, gk) # Do public preprocessing batch = ExplodedConvArray{eltype(batch)}(cdims, batch); # Run on encrypted data under the encryption context Cresult = ctx(model)(encrypt(kp.pub, batch)) # Decrypt the answer decrypt(kp, Cresult) 

, . ( тДЫ, modswitch, keyswitch ..) , . , , , , .

рдирд┐рд╖реНрдХрд░реНрд╖


тАФ . Julia . RAMPARTS ( paper , JuliaCon talk ) : Julia- - PALISADE. Julia Computing RAMPARTS Verona, . , . . , , .

, ToyFHE . , , , .

Source: https://habr.com/ru/post/hi478514/


All Articles